这个 C++ 代码,也许令人惊讶,打印出 1
。
#include <iostream>
std::string x();
int main() {
std::cout << "x: " << x << std::endl;
return 0;
}
x
是一个函数原型(prototype),似乎被看作是一个函数指针,C++ Standard section 4.12 Boolean conversions说:
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.
但是,x
永远不会绑定(bind)到函数。正如我所料,C 链接器不允许这样做。但是在 C++ 中,这根本不是问题。谁能解释这种行为?
最佳答案
这里发生的是函数指针被隐式转换为 bool
.这由 [conv.bool]
指定:
A zero value, null pointer value, or null member pointer value is converted to
false
; any other value is converted totrue
其中“空指针值”包括空函数指针。由于函数名衰减得到的函数指针不能为空,因此给出true
.您可以通过包含 << std::boolalpha
来查看这一点在输出命令中。
以下确实会导致 g++ 中的链接错误:(int)x;
关于是否允许这种行为,C++14 [basic.odr.ref]/3
说:
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 [...]
确实涵盖了这种情况,因为 x
在输出表达式中查找 x
的声明以上就是独特的结果。然后在 /4
我们有:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
所以程序格式错误但不需要诊断,这意味着程序的行为是完全未定义的。
顺便说一句,这个子句暗示 x();
不需要链接错误。要么,但是从实现质量的角度来看;那太傻了。类(class)g++
选择这里对我来说似乎很合理。
关于c++ - 为什么 C++ 链接器允许未定义的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27136524/