The function I want to run:
struct foo;
void bar(const foo* p = 0);
How I call the function:
auto thread = std::thread(&bar, NULL);
The warning:
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]
What am I missing here?
When I call the function with non-NULL
argument, the warning goes away.
The trouble is that NULL
is a bit ambiguous.
While it is semantically a pointer, it can (and in your implementation is) of integral type.
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
.
[...]
So your implementation decided to make it plain 0
for backwards-compatibility, but to flag it for extra diagnostics.
Which is actually a laudable decision for promoting portable code.
Though it's a shame noone could hop into a time-machine and just make NULL
identical to nullptr
in the standard, so the ambiguity does not exist.
To resolve the error, use nullptr
instead of NULL
or, more involved and not so nice, a pointer of the proper type.
The problem is that NULL
is a macro with value 0. Template argument deduction deduced the type of NULL
as int
(as you can see from the end of the warning). Yet NULL
is by convention used for pointer arguments, not integral arguments. So the compiler warns you that you're passing a NULL
argument to an int
parameter. To make things worse, this is technically wrong as that non-const integer 0 argument is no longer guaranteed to be convertable to a null pointer.
The correct solution is nullptr
. This is, as the name already hints, a pointer instead of an integer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With