Search code examples
c++pointersnullintegeroverloading

Ambiguous overload of pointer and integer?


The following overloaded function,

void foo(const void*)
{
  printf("first");
}

void foo(unsigned int)
{
  printf("second");
}

generates an ambiguous overload in this case

foo((int)0);

but not in this one

foo((int)1);

Why? Is it because people still use NULL? And what's the best way to get around the problem, without explicit cast?

(I'm compiling with GCC 8.3.0-C++11 on Ubuntu 18.04)

Godbolt conformance view

EDIT

As some of you pointed out in the comments, (int)0 compiles without errors, actually (at least on GCC 8.3.0, with C++11 std). The problem I had was only with foo(0), and I get why now.


Solution

  • The literal 0 has special meaning in C and C++, as it's also a null pointer literal. This is how NULL works.

    If you're calling the function with a literal, instead of foo(0) you could do foo(0u), which works because 0u already has the type unsigned int, so there's no conversion needed to call the integer overload. If you're calling foo with an integer variable, there shouldn't be any conflict. (demo here)

    As mentioned in the comments, (int)0 shouldn't cause any conflict, and GCC 8.3 doesn't produce any error with foo((int)0) in C++11 mode, but does in C++98 mode (and so does clang). As mentioned by @StoryTeller-UnslanderMonica in the comments, this is caused by a defect http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#903 that wasn't retroactively applied to C++98.