次のコードは、gcc バージョン 4.8.0 で失敗しました。
#include <thread>
#include <cassert>
int main() {
std::thread::id nobody;
assert( nobody != std::this_thread::get_id() );
};
この動作は正しいですか?
更新: Jonathan Wakelyは、コンパイラとリンカーの両方に渡す必要があると彼が言う問題 (以下のコメント)を親切に調べました。-pthread
私がそうすれば、コードはgcc 4.7.2でも失敗しません。したがって、回答は引用された電子メールとは明らかに関係がありません。ありがとうジョナサン!
以下は、2011 年に書かれ
た gcc 開発者の Jonathan Wakely のメールからの直接の引用です。
std::thread::id のすべての比較演算子は未定義の動作に依存しています。これは、thread::id が単なる pthread_t であるためです。
[...]
2) operator== は、無効なスレッド ID に対して定義されていない pthread_equal を使用します。POSIX は次のように述べています。
If either t1 or t2 are not valid thread IDs, the behavior is undefined.
変。次のコード:
#include <iostream>
#include <thread>
int main() {
std::cout << "Started" << std::endl;
std::thread::id nobody;
if ( nobody != std::this_thread::get_id() ) {
std::cout << "OK" << std::endl;
}
std::cout << "Finished" << std::endl;
}
生成:
Started
OK
Finished
ここで確認してください。ただし、コードは 4.7.2 で失敗します。
C++11 標準にはアクセスできませんが、最新の標準ドラフトn3485 [thread.thread.id]から
タイプ thread::id のオブジェクトは、実行の各スレッドに一意の識別子を提供し、実行のスレッドを表さないすべてのスレッド オブジェクトに単一の個別の値を提供します (30.3.1)
に続く
id() noexcept; 効果: タイプ id のオブジェクトを構築します。事後条件: 構築されたオブジェクトは、実行のスレッドを表していません。
これは、あなたが観察しているのは gcc のバグであることを暗示しているようです