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?
Used the GCC compiler to compile the exp. c file. The error: undefined reference to function show() has appeared on the terminal shell as predicted. To solve this error, simply open the file and make the name of a function the same in its function definition and function call.
An “Undefined Reference” error occurs when we have a reference to object name (class, function, variable, etc.) in our program and the linker cannot find its definition when it tries to search for it in all the linked object files and libraries.
You can fix undefined reference in C++ by investigating the linker error messages and then providing the missing definition for the given symbols. Note that not all linker errors are undefined references, and the same programmer error does not cause all undefined reference errors.
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.
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