警告:将 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
,或者使用正确类型的指针,更复杂但不太好。
我想要的功能运行:
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
,或者使用正确类型的指针,更复杂但不太好。