std::thread::id 默认构造函数不应该创建一个"NULL" id吗?

Should not std::thread::id default constructor create a "NULL" id?

本文关键字:id 一个 NULL 默认 thread 构造函数 不应该 std 创建      更新时间:2023-10-16

以下代码在我的gcc 4.8.0版本中失败:

#include <thread>
#include <cassert>
int main() {
    std::thread::id nobody;
    assert( nobody != std::this_thread::get_id() );
};

这个行为正确吗?

UPDATE: Jonathan Wakely亲切地看着这个问题,他说(在下面的评论中)-pthread必须传递给编译器和链接器。如果我这样做,代码也不会与gcc 4.7.2失败。因此,答案显然与引用的电子邮件无关。谢谢乔纳森!


以下是gcc开发者Jonathan Wakely在2011年写的邮件中的一些直接引用:

std::thread::id上的所有比较操作符都依赖于undefined行为,因为我们的thread::id只是一个pthread_t。

[…)

2) operator==使用pthread_equal,无效时未定义线程id, POSIX说:

   If either t1 or t2 are not valid thread IDs, the behavior is undefined.
虽然它是两年前写的,但它可能仍然适用。目前,我无法检查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

我没有访问c++ 11标准,但从最新的标准草案n3485 [thread.thread]。id]

thread::id类型的对象为每个正在执行的线程提供一个唯一的标识符,并为所有不代表正在执行的线程的线程对象提供一个单独的值(30.3.1)

后接

id () noexcept;构造一个id类型的对象。后置条件:构造的对象不代表执行线程。

这似乎暗示你正在观察的是gcc

中的一个bug