警告:将 NULL 传递给 'std::thread::thread

warning: passing NULL to non-pointer argument of ‘std::thread::thread

本文关键字:thread std NULL 警告      更新时间:2023-10-16

我想运行的函数:

struct foo;
void bar(const foo* p = 0);

我如何调用函数:

auto thread = std::thread(&bar, NULL);

警告:

foobar.h:223:9: 警告:将 NULL 传递给 'std::thread::thread(_Callable&&, _Args&& ...) 的非指针参数 2 [_Callable = void (*)(const foo*), _Args = {int}]' [-Wconversion-null]

我在这里错过了什么?

当我使用非NULL参数调用函数时,警告消失了。

问题是NULL有点模棱两可。
虽然它在语义上是一个指针,但它可以(在你的实现中是)整数类型。

18.2 [support.types]类型

3 宏NULL是本国际标准 (4.10) 中实现定义的 C++ null 指针常量

4.10 指针转换 [conv.ptr]

1 空指针常量是值为零或 prvalue 为 std::nullptr_t 的整数文本 (2.14.2)。
[...]

因此,您的实现决定将其简单0向后兼容,但将其标记为额外的诊断。

对于推广可移植代码来说,这实际上是一个值得称赞的决定。
虽然很遗憾没有人可以跳进时间机器,只是让NULL与标准中的nullptr相同,所以歧义不存在。

若要解决此错误,请使用 nullptr 而不是 NULL 或者,使用更复杂且不太好的指针,正确类型的指针。

问题是NULL是一个值为 0 的宏。模板参数推导推断出NULL的类型int(从警告的末尾可以看到)。然而,按照惯例,NULL用于指针参数,而不是积分参数。因此,编译器会警告您正在将NULL参数传递给int参数。更糟糕的是,这在技术上是错误的,因为非常量整数 0 参数不再保证可转换为空指针。

正确的解决方案是 nullptr .顾名思义,这是一个指针而不是整数。