This C++ code, perhaps surprisingly, prints out 1
.
#include
std::string x();
int main() {
std::cout << \"x: \" <&l
What's happening here is that the function pointer is implicitly converted to bool
. This is specified by [conv.bool]
:
A zero value, null pointer value, or null member pointer value is converted to
false
; any other value is converted totrue
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::boolalpha
in 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]/3
says:
A function whose name appears as a potentially-evaluated expression is odr-used if it is the unique lookup result or the selected member of a set of overloaded functions [...]
which does cover this case, since x
in the output expression is looked up to the declaration of x
above and that is the unique result. Then in /4
we have:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
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 that g++
has chosen here seems reasonable to me.