我有以下代码段main.c,下面是somefile.h文件
#include "somefile.h"
extern int var = 10000;
int main()
{
cout << var << endl;
return 0;
}
和somefile.h包含
int var;
我的问题是,当我执行此代码时,它会产生输出10000,但为什么这不是重新定义错误。因为我认为extern int var = 10000;
是定义。此外,如果我在somefile.h中为var
分配了一些值,它会给我一个错误,说明重定义是预期的。我正在使用VS 2010.
答案 0 :(得分:3)
这个问题标记为C和C ++,但这些是不同的语言。我的回答是关于C.
如果您的代码在文件范围包含序列int var; /* ... */ int var = 10000;
,那么这在C中是合法的。
行int var;
被称为暂定定义,它有点像函数的前向声明,但对于变量。如果有变量的后续定义,那么该定义将取代它;否则暂定定义计数,变量将初始化为0
。
您的extern
关键字没有区别,因为除非您专门使用extern
关键字,否则无论如何在文件范围定义的变量都是static
。
但是,如果添加了include
somefile.h的第二个翻译单元,则行为未定义。这是因为两个不同的翻译单元都定义了变量var
。您的链接器可能会对此进行诊断,但C标准并不要求它。
如果你给somefile.h中的行一个初始值设定项,例如int var = 5000;
然后这是编译器必须诊断的多重定义错误。
答案 1 :(得分:2)
我认为OP并没有像他为讨论暂定的定义那样塑造他的榜样。除了语言律师的东西,以及C和C ++之外,也许应该说出基本的想法:
我从你的例子中创建了一个带有两个源文件的迷你编程来演示这个想法。第二个c文件包含一个将在main.c中使用的函数。两个c文件都包含相同的头文件。头文件提供了相互信息交换:两个c文件都知道另一个提供的资源(变量,函数)。包括标题还可以确保c文件中的定义与其他人看到的声明匹配。
头文件本身不会创建任何内容。
<强> somefile.h 强>
// make var known to whoever it may concern:
extern int var; // declaration, nothing created
extern int computeHalfVar(); // declare a function
<强> halfVar.c 强>
// The header contains the declaration of var
// which is defined in main.c
#include "somefile.h"
int computeHalfVar() { return var/2; }
<强>的main.c 强>
#include <iostream>
// declares computeHalfVar() which we'll use
#include "somefile.h"
using namespace std;
// create and initialize var.
// This is the variable everybody else will use.
// The type must match the declaration in the header.
int var = 10000;
int main()
{
cout << var << endl;
// Use a function defined in a different translation unit.
// The compiler knows the name and signature from the header we included.
cout << computeHalfVar() << endl;
return 0;
}
答案 2 :(得分:0)
它不仅仅是重新定义错误。它是&#34; C274:&#39; var&#39; :重新定义;多次初始化&#34;错误。实际上它是多次初始化。如果您查阅Microsoft文档,请明确说明:
标识符不止一次初始化。
http://msdn.microsoft.com/en-us/library/88cc602k%28v=vs.90%29.aspx