警告:将 NULL 传递给“std::thread::thread”的非指针参数

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

我想要的功能运行:

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

我如何调用函数:

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

警告:

foobar.h:223:9: warning: passing NULL to non-pointer argument 2 of ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (*)(const foo*), _Args = {int}]’ [-Wconversion-null]

我在这里错过了什么?

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

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

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

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

18.2 Types [support.types]

3 The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10).

4.10 Pointer conversions [conv.ptr]

1 A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t.
[...]

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

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

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