为什么C++编译器允许 extern 关键字与定义相结合

Why does the C++ compiler allow extern keyword combined with definition?

本文关键字:关键字 定义 相结合 extern C++ 编译器 为什么      更新时间:2023-10-16

我不小心在使用 extern 关键字时出错,然后发现编译器允许我的代码行。为什么允许以下程序?编译器是否去除了 extern 关键字?它甚至没有发出警告。

#include <iostream>
extern void test() { std::cout << "Hello world!" << std::endl; };
int main()
{
    test();
}

这并不罕见,事实上,C++内部做同样的事情,请注意 1.4/6 所说的:

库中的模板、类、函数和对象具有外部链接

库中的模板显然也有定义。他们为什么不呢!

看看 3.1/2 和 3.4/2(强调后加)怎么说:

声明

是一个定义,除非它声明一个函数而不指定函数的主体 (8.4),[或] 它包含 extern 说明符 (7.1.1) 或链接规范25 (7.5),并且既不是初始值设定项也不是函数体
[...]
当一个名称有外部链接时,它所表示的实体可以用其他翻译单元的范围或同一翻译单元的其他范围的名称来引用。

你的声明有一个函数体,所以它是一个定义,这是明确、完全允许的。该函数具有外部链接,这意味着您可以通过另一个翻译单元中范围内的名称来引用它,但您不需要这样做。

在当前的翻译单元中,您仍然可以完全按其名称来称呼它,这就是您正在做的事情。

请注意,命名空间范围内有一个关于名称的子句,因此无论如何,您对 extern 关键字的使用都是多余的。