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

时间:2015-01-22 09:48:47

标签: c++ extern

我意外地使用extern关键字出错,然后发现编译器允许我的代码行。为什么允许以下程序?编译器是否剥离了extern关键字?它甚至没有发出警告。

#include <iostream>

extern void test() { std::cout << "Hello world!" << std::endl; };

int main()
{
    test();
}

1 个答案:

答案 0 :(得分:3)

这并不罕见,事实上,C ++内部做的完全相同,请注意1.4 / 6的内容:

  

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

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

参见3.1 / 2和3.4 / 2(重点补充)必须说:

  

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

你的声明有一个函数体,所以它是一个定义,而且这是明确的,完全允许的。该功能具有外部链接,这意味着您可以通过其他翻译单元中的作用域中的名称引用它,但您

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

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