c++ - 为什么 C++ 链接器允许未定义的函数?

标签 c++ compilation linker language-lawyer undefined-function

这个 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 to true

其中“空指针值”包括空函数指针。由于函数名衰减得到的函数指针不能为空,因此给出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/

相关文章:

c++ - 如何通过zeromq发送包含\0的序列化跳跃运动帧?

java - 在同一包中的已编译类中看不到静态方法

编译时间恶意软件可能吗?

c# - 在 C# 中静态链接

c++ - 如何更改automake的CXXLINK中的顺序?

c++ - 准确检测正方形和圆形之间重叠的算法?

c++ - 在打开 vsync 的情况下执行 glTexImage2D 时出现奇怪的延迟

C++:互斥和释放

compilation - 在编译字中编译匿名字

c - Raspberry Pi 上的 rodata