7

次のコードは、gcc バージョン 4.8.0 で失敗しました。

#include <thread>
#include <cassert>

int main() {
    std::thread::id nobody;

    assert( nobody != std::this_thread::get_id() );
};

この動作は正しいですか?

4

2 に答える 2

7

更新: 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.
2年前に書かれたものですが、おそらく今でも通用します。現時点では、gcc コードベースを調べて詳細を確認することはできません。

変。次のコード:

#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 で失敗します。

于 2013-04-17T16:25:22.353 に答える
6

C++11 標準にはアクセスできませんが、最新の標準ドラフトn3485 [thread.thread.id]から

タイプ thread::id のオブジェクトは、実行の各スレッドに一意の識別子を提供し、実行のスレッドを表さないすべてのスレッド オブジェクトに単一の個別の値を提供します (30.3.1)

に続く

id() noexcept; 効果: タイプ id のオブジェクトを構築します。事後条件: 構築されたオブジェクトは、実行のスレッドを表していません。

これは、あなたが観察しているのは gcc のバグであることを暗示しているようです

于 2013-04-17T16:15:32.327 に答える