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

10,430

Solution 1

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.

Solution 2

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.

Share:
10,430

Related videos on Youtube

gsamaras
Author by

gsamaras

Yahoo! Machine Learning and Computer Vision team, San Francisco, California. Masters in Data Science. Received Stackoverflow Swag, Good Samaritan SO swag and "10 years Stackoverflow" Swag x2! In Top 10 users of my country.

Updated on September 16, 2022

Comments

  • gsamaras
    gsamaras over 1 year

    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.

    • cdhowie
      cdhowie about 9 years
      You should really be using nullptr instead of NULL in C++ >= 11.
    • cdhowie
      cdhowie about 9 years
      @molbdnilo No, _Args is deduced from the arguments supplied to the std::thread constructor, which implies that whatever the NULL macro evaluates to has type int. The definition of NULL is implementation-defined, so we'd have to know how it's defined in OP's case to understand why it has type int. (Typically it's defined as ((void *)0) in older C code. Obviously it has a different definition here -- probably just 0, and 0 is implicitly convertible to any pointer type, but some random int, which is what the 0 becomes as a parameter to std::thread(), cannot.)
  • Deduplicator
    Deduplicator about 9 years
    Since when is NULL a macro with value 0, instead of an implementation-defined universal null-pointer constant (which might be plain 0)?
  • MSalters
    MSalters about 9 years
    @Deduplicator: Any null pointer constant has value zero, although the type may differ somewhat.
  • Deduplicator
    Deduplicator about 9 years
    That's simply wrong. My answer has the quotes to proove it.
  • MSalters
    MSalters about 9 years
    @Deduplicator: You quote the standard which literally states " integer literal with value zero", and apparently I'm wrong when I say it's a macro with value zero ?? I don't follow your logic.
  • Deduplicator
    Deduplicator about 9 years
    No, I'm quoting the requirements for NULL, which is null pointer constant, and the definition of null pointer constant, which lists as one possibility a zero integral literal. There is that other possibility too.
  • MSalters
    MSalters about 9 years
    @Deduplicator: One possibility which does not apply to the problem at hand, as we can derive from the warning. I agree that other compilers can indeed choose to use nullptr.
  • Deduplicator
    Deduplicator about 9 years
    Well, if you at least hinted that that part was implementation-defined, instead of cast in stone... especially as the ambiguity of NULL was at the heart of the problem.