This C++ code, perhaps surprisingly, prints out 1.
#include <iostream>
std::string x();
int main() {
std::cout << "x: " << x << std::endl;
return 0;
}
x is a function prototype, which seems to be viewed as a function pointer, and C++ Standard section 4.12 Boolean conversions says:
4.12 Boolean conversions [conv.bool] 1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (8.5), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.
However, x is never bound to a function. As I would expect, the C linker doesn't allow this. However in C++ this isn't a problem at all. Can anyone explain this behavior?
What's happening here is that the function pointer is implicitly converted to
bool. This is specified by[conv.bool]:where "null pointer value" includes null function pointers. Since the function pointer obtained from decay of a function name cannot be null, this gives
true. You can see this by including<< std::boolalphain the output command.The following does cause a link error in g++:
(int)x;Regarding whether this behaviour is permitted or not, C++14
[basic.odr.ref]/3says:which does cover this case, since
xin the output expression is looked up to the declaration ofxabove and that is the unique result. Then in/4we have:so the program is ill-formed but no diagnostic is required, meaning that the program's behaviour is completely undefined.
Incidentally this clause implies that no link error is required for
x();either, however from a quality-of-implementation angle; that would be silly. The course thatg++has chosen here seems reasonable to me.