我正在使用Visual Studio 2012进行编程原理和练习练习。当尝试编译下面的源代码时,我收到链接器错误:
未解决的符号int foo。
我不明白为什么这个符号没有得到解决。
extern int foo;
void print_foo();
void print(int);
#include "my.h"
#include "../../std_lib_facilities.h"
void print_foo()
{
cout<<foo<<'\n';
}
void print(int i)
{
cout<<i<<'\n';
}
#include "my.h"
int main(){
int foo = 7;
print_foo();
print(99);
}
答案 0 :(得分:5)
extern int foo;
这是声明。它告诉编译器“在某处定义的全局命名空间中将会有一个名为foo
的{{1}}变量”。
int
这在函数int main(){
int foo = 7;
// ...
}
中定义了foo
类型的局部变量int
,并将其初始化为7.此局部变量在main()
之外不可见。
您未执行的操作实际上是全局命名空间中的 define main()
。为此,请在包含后将此行添加到 foo
或my.cpp
的中
use.cpp
这定义了全局命名空间中类型为int foo;
的名为foo
的变量。 (作为静态存储持续时间的对象,默认情况下int
初始化为零,但如果需要,也可以提供不同的初始化程序。)然后,链接器应该能够解析对全局{{1当你将目标文件链接在一起时,它就在foo
中。
您只需定义 foo
一次非常重要,但您可以根据需要声明。否则会违反一个定义规则,如果幸运,会导致链接器错误,如果不幸,则会导致未定义的行为。
答案 1 :(得分:2)
本声明
extern int foo;
是名称foo的声明。它不是foo的定义。
您必须初始化此变量,它将是一个定义。例如
extern int foo = 0;
虽然我的代码中没有任何意义。
也许你的意思如下。我想模块中定义的变量是因为如果只有一个模块,我看不到使用标题的感觉。
/* my.cpp */
#include "../../std_lib_facilities.h"
extern int foo = 0;
void print_foo();
void print(int);
void print_foo()
{
cout<<foo<<'\n';
}
void print(int i)
{
cout<<i<<'\n';
}
int main(){
extern int foo;
foo = 7;
//...
如果您想使用标题,那么代码可能看起来像
/* my.h */
extern int foo;
void print_foo();
void print(int);
/* my.cpp */
#include "my.h"
#include "../../std_lib_facilities.h"
int foo;
void print_foo()
{
cout<<foo<<'\n';
}
void print(int i)
{
cout<<i<<'\n';
}
/* use.cpp */
#include "my.h"
int main(){
extern int foo;
foo = 7;
print_foo();
print(99);
}