对不起,伙计们,我知道我的英语不好,但我做了一些例子,让我的问题更清晰。
答.cpp
#include <iostream>
using namespace std;
void funcfoo(){
cout << "test only" << endl;
}
int varfoo = 10;
乙.cpp
#include <iostream>
using namespace std;
extern void funcfoo();
extern int varfoo;
int main(){
funcfoo();
cout << varfoo;
return 0;
}
然后我像这样编译它"cl b.cpp a.cpp">
我的问题是。为什么当我删除"void funcfoo((之前 extern 关键字"时它工作正常,但是当我删除 extern 关键字时在 int var foo 之前,我收到错误?
问题是每一行代码的含义。 int varfoo
是变量的定义,而void funcfoo()
只是一个声明。您可以提供实体的多个声明,但只能提供一个定义。提供声明且仅提供变量声明的语法是通过添加 extern
关键字:extern int varfoo;
是一个声明
3.1 [basic.def]/2 声明是一个定义,除非它声明一个函数而不指定函数的主体 (8.4(,它包含 extern 说明符 (7.1.1( 或链接规范25 (7.5(,既不是初始值设定项也不是函数体 [...]
当您从extern void funcfoo();
中删除extern
时,您将向前声明它,因此下面的代码将知道funcfoo()
是什么。 如果你要对一个变量这样做,你实际上是在实例化它,并且会与你的另一个文件发生冲突。因此,extern
说"它存在,相信我;)"它从您的其他文件中解析。
另一种思考方式是,当你做int varfoo内存时,内存被分配来保存变量,所以它既是一个定义又是一个声明,当你做int foo((时,函数被声明但未定义,所以在某种程度上没有分配内存。对于函数,链接默认是外部的,所以删除它并不重要,但对于变量,如果你说extern int varfoo编译器不会为它分配内存 - 它将假设变量是在其他地方定义的。
这可能很晚,但我希望这在某种程度上有所帮助。检查下面的链接,它将提供extern是什么以及它是如何工作的。
http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/
谢谢