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

时间:2015-01-14 19:57:52

标签: c++ templates c++11 perfect-forwarding nullptr

我想要运行的功能:

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

我如何调用该函数:

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

警告:

  

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

我在这里缺少什么?

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

2 个答案:

答案 0 :(得分:2)

问题是NULL有点含糊不清 虽然它在语义上是一个指针,但它可以(并且在你的实现中)是整数类型。

  

18.2类型[support.types]

     

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

  

4.10指针转换[conv.ptr]

     

1 空指针常量是一个整数文字(2.14.2),其值为零或prvalue类型为std::nullptr_t
  [...]

因此,您的实现决定使其0为向后兼容性,但标记它以进行额外诊断。

这对于推广便携式代码实际上是一个值得称道的决定 虽然很遗憾没有人可以跳进时间机器,只是让NULL与标准中的nullptr相同,所以不存在模糊性。

要解决此错误,请使用nullptr代替NULL,或使用更多参与且不太好的指针,使用正确的类型。

答案 1 :(得分:1)

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

正确的解决方案是nullptr。正如名称已经提示的那样,这是指针而不是整数。