Given the following code snippet:
#include <string>
#include <iostream>
int main()
{
std::string prefix("->"), middle(), suffix("<-");
std::cout << "Test: " << prefix << middle << suffix << std::endl;
return 0;
}
The advanced C++ programmer will immediately see that middle()
is not calling std::string
's default ctor, instead it's a function declaration.
What's interesting though: Why does gcc produce the following output:
Test: ->1<-
in contrast to Visual Studio's linker error? Does anybody know what's going on here?
A function pointer will be converted to bool
when using with cout
.
Why the function pointer is not converted to a void *
implicitly, which is what operator << overloads on? because function pointers are not object pointers.
C++11 §4.10/2:
A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject). The null pointer value is converted to the null pointer value of the destination type.
As Yu said, the function pointer is being converted to bool
.
The g++ optimizer is evidently pre-evaluating the conversion, while Visual C++ actually generates code to test if the function address is null, which requires the linker to provide the function address.
The rule is that
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
The function is odr-used because you're using its address. By not providing a definition, you're violating this rule, and the Standard doesn't require a diagnostic, meaning the toolchain is free to do anything it wants.
Visual C++ is generating a diagnostic, although it's not required to.
g++ is giving the actual result of conversion to bool
, since it knows that decay of an actual function to a function pointer can never produce a null function pointer.
But formatting your hard drive would be equally valid, since the Standard doesn't say what the toolchain can or can't do here.
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