标准库不会为重复定义引发错误

standard library not raising error for duplicate definition

为什么这不是 return 重复函数定义的错误,因为 c++ 标准库进行外部链接。

这不应该是函数重载,因为它是 double(double,double) 类型,与 math.h

中定义的 pow 完全相同
#include <iostream>
#include <math.h>

double pow(double base, double exponent) {
    return 1;
}

int main() {
    std::cout << pow(2, 2);
}

函数签名pow(double, double)保留给全局命名空间中的语言实现。通过定义保留名称,程序的行为是未定义的。

那么程序的行为是未定义的,你不能保证会“为重复定义引发错误”。

相关标准规则(来自最新草案):

[reserved.names.general]

If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by [library], its behavior is undefined.

[extern.names]

Each name from the C standard library declared with external linkage is reserved to the implementation for use as a name with extern "C" linkage, both in namespace std and in the global namespace.

Each function signature from the C standard library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage, or as a name of namespace scope in the global namespace.

Why does this not return an error for duplicate function definition...?

因为C库提供的pow的定义不需要在包含的头文件中。此头文件 (math.h) 可能仅包含其声明。在这种情况下,生成的翻译单元可能如下所示:

...
double pow(double, double);
...

double pow(double base, double exponent)
{
    return 1;
}

int main()
{
    std::cout << pow(2, 2);
}

这个翻译单元绝对没有问题。但是,问题发生在 linking 期间,因为 linker 可以 link 你的 pow 在机器代码级别调用两个不同的函数——由C 库和其他由翻译单元创建的目标文件提供的。

linker 实际要做的事情并没有被 C++ 标准定义。它只是说您的代码的行为未定义。