为什么 C++ 编译器允许 extern 关键字与定义相结合?
Why does the C++ compiler allow extern keyword combined with definition?
我不小心在使用extern
关键字时出错,然后发现编译器允许我的代码行。为什么允许以下程序?编译器是否去掉了 extern 关键字?它甚至没有发出警告。
#include <iostream>
extern void test() { std::cout << "Hello world!" << std::endl; };
int main()
{
test();
}
这并不罕见,事实上,C++ 内部做着完全相同的事情,请注意 1.4/6 所说的:
The templates, classes, functions, and objects in the library have external linkage
库中的模板显然也有定义。他们为什么不呢!
看看 3.1/2 和 3.4/2(强调)有什么要说的:
A declaration is a definition unless it declares a function without specifying the function’s body (8.4), [or] it contains the extern specifier (7.1.1) or a linkage-specification25 (7.5) and neither an initializer nor a functionbody
[...]
When a name has external linkage , the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.
你的声明有一个函数体,所以它是一个定义,这是明确的,完全允许的。该函数具有外部链接,这意味着您 可以 通过另一个翻译单元中范围内的名称引用它,但您 不需要 这样做。
您仍然完全可以在当前的翻译单元中使用它的名字来调用它,这就是您正在做的事情。
请注意,在命名空间范围内有一个关于名称的子句,因此您对 extern
关键字的使用无论如何都有些多余。
我不小心在使用extern
关键字时出错,然后发现编译器允许我的代码行。为什么允许以下程序?编译器是否去掉了 extern 关键字?它甚至没有发出警告。
#include <iostream>
extern void test() { std::cout << "Hello world!" << std::endl; };
int main()
{
test();
}
这并不罕见,事实上,C++ 内部做着完全相同的事情,请注意 1.4/6 所说的:
The templates, classes, functions, and objects in the library have external linkage
库中的模板显然也有定义。他们为什么不呢!
看看 3.1/2 和 3.4/2(强调)有什么要说的:
A declaration is a definition unless it declares a function without specifying the function’s body (8.4), [or] it contains the extern specifier (7.1.1) or a linkage-specification25 (7.5) and neither an initializer nor a functionbody
[...]
When a name has external linkage , the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.
你的声明有一个函数体,所以它是一个定义,这是明确的,完全允许的。该函数具有外部链接,这意味着您 可以 通过另一个翻译单元中范围内的名称引用它,但您 不需要 这样做。
您仍然完全可以在当前的翻译单元中使用它的名字来调用它,这就是您正在做的事情。
请注意,在命名空间范围内有一个关于名称的子句,因此您对 extern
关键字的使用无论如何都有些多余。