0

I have the following:

void func(const char *p) { std::cout << p << "\n"; }
void func(std::nullptr_t p) { std::cout << "<null>\n"; }

int main()
{
    func("test");
    char *p=nullptr;
    func(p);
    func(nullptr);
    return 0;
}

func("test") is always called. With func(p) commented, func(nullptr) is called, but when func(p) is not commented neither of them are called. Why not? Why does func(p) with p==nullptr not call func(nullptr), but to calls func(const char*) instead?

[edit]
Based on responses my conclusion is that func(...) is called based on the type of the parameter, and p is of type char*, setting p's value to nullptr does not change the type and will not change that func(char*) is called - as the accepted answer also explains.

slashmais
  • 7,069
  • 9
  • 54
  • 80
  • 2
    Related: http://stackoverflow.com/questions/23283772/is-printing-a-null-pointer-undefined-behavior – David G Jun 09 '14 at 18:23
  • Can you modify it to not attempt to use the null pointer `func(p)` uses the null pointer, which is Undefined Behavior. What happens when you make that change? See http://ideone.com/gSNG6m – Dave S Jun 09 '14 at 18:31
  • @DaveS: don't know if I understand what you mean, but if p points to a valid c-string, all works fine. – slashmais Jun 09 '14 at 18:35
  • @slashmais Because if you're going to print a null pointer, that sets a bit in the stream's error mask. When that happens you can no longer perform output unless you clear the error mask again. – David G Jun 09 '14 at 18:38
  • @0x499602D2: yes I saw that in the linked-to question, and is the reason. I've edited my question to: why is func(nullptr) not called with p==nullptr? aaaah - ok now I see: the functions are called based on type, and in this case nullptr is a value allocated to p and it does not change p's type. – slashmais Jun 09 '14 at 18:42
  • 1
    @slashmais That's correct. The compiler has to decide which version of `func` to call at compile time, so it's not possible for this to be based on an argument variable's current value--only its static type. – dlf Jun 09 '14 at 18:47
  • @dlf: yes, and the only instance where it would work by-value is with variadic-templates, I think - got to test this idea now ;) – slashmais Jun 09 '14 at 18:53
  • 2
    Please update your question as it is no longer internally consistent. You will get output from all three function calls in all cases; the question is, _what_ output. Update it by rephrasing and cleaning up, not by appending yet more "edit:" passages without any punctuation or capital letters. – Lightness Races in Orbit Jun 09 '14 at 19:03

1 Answers1

3

The precise content of your question is actually deeply mired in confusion, now, because the reason you were seeing things "not being called" was that your original code was attempting to stream a null character pointer, which sets an error flag on the stream and prevents it from working again until it is corrected. Anyway, here's the gist of the answer:


You can't assign nullptr to a char* and expect that char* to magically transform into a std::nullptr_t. Your pointer is still a char*, and it has the value nullptr.

The benefit of std::nullptr_t is in given the null pointer literal its own distinct type that doesn't convert to integer types; that doesn't mean that you can expect to use the type std::nullptr_t wherever a pointer has the value 0.

slashmais
  • 7,069
  • 9
  • 54
  • 80
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055