解析extern
来源:互联网 发布:联通大数据精准营销 编辑:程序博客网 时间:2024/05/16 01:20
1、声明外部变量
现代编译器一般采用按文件编译的方式,因此在编译时,各个文件中定义的全局变量是
互相透明的,也就是说,在编译时,全局变量的可见域限制在文件内部。下面举一个简单的例子。创建一个工程,里面含有A.cpp和B.cpp两个简单的C++源文件:
//A.cpp
int i;
void main()
{
}
//B.cpp
int i;
这两个文件极为简单,在A.cpp中我们定义了一个全局变量i,在B中我们也定义了一个全局变量i。
我们对A和B分别编译,都可以正常通过编译,但是进行链接的时候,却出现了错误,错误提示如下:
Linking...
B.obj : error LNK2005: "int i" (?i@@3HA) alreadydefined in A.obj
Debug/A.exe : fatal error LNK1169: one or moremultiply defined symbols found
Error executing link.exe.
A.exe - 2 error(s), 0 warning(s)
但是到了链接阶段,要将各个文件的内容“合为一体”,因此,如果某些文件中定义的全局变量名相同的话,在这个时候就会出现错误,也就是上面提示的重复定义的错误。
//A.cpp
void main()
{
}
//B.cpp
int i;
Compiling...
A.cpp
C:/Documents andSettings/wangjian/桌面/try extern/A.cpp(5) : error C2065: 'i' :undeclared identifier
Error executing cl.exe.
A.obj - 1 error(s), 0 warning(s)
//A.cpp
extern int i;
void main()
{
}
//B.cpp
int i;
2、在C++文件中调用C方式编译的函数
C方式编译和C++方式编译
相对于C,C++中新增了诸如重载等新特性,对于他们的编译,必然有一些重要的区别。
我们将下面的小程序分别按C和C++方式编译,来探讨两种编译方式的区别。
int i;
int func(int t)
{
}
void main()
{
}
COMM
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
多文件程序中的函数调用
//A.CPP
void func();
void main()
{
}
//B.CPP
void func()
{
}
如果没有声明的话,编译A.CPP时就会出错。因为编译器的目光只局限于被编译文件,必须通过加入函数声明来告诉编译器:“某个函数是定义在其它的文件中的,你要放行!”,这一点跟用extern来声明外部全局变量是一个道理。
不同编译方式下的函数调用
//A.CPP
void func();
void main()
{
}
//B.C
void func()
{
}
Linking...
A.obj : error LNK2001: unresolved external symbol"void __cdecl func(void)" (?func@@YAXXZ)
Debug/A.exe : fatal error LNK1120: 1 unresolvedexternals
Error executing link.exe.
A.exe - 2 error(s), 0 warning(s)
原因就在于不同的编译方式产生的冲突。
call
如果B文件也是按照C++方式编译的,那么B中的func函数名也会被编译器改成?func1@@YAXXZ,这样的话,就没有任何问题。
//A.CPP
extern "C"
{
}
void main()
{
}
3、补充
同2一样,仍然是C,C++混合编程的情形,考虑下面的程序:
//A.CPP
extern int i;
void main()
{
}
//B.C
int i;
Linking...
A.obj : error LNK2001: unresolved external symbol"int i" (?i@@3HA)
Debug/A.exe : fatal error LNK1120: 1 unresolvedexternals
Error executing link.exe.
A.exe - 2 error(s), 0 warning(s)
因而,我们只用extern int i;来声明还不够,必须告诉编译器,全局变量i是以C方式编译的,
它会被重命名为_i,而不是?i@@3HA。
//A.CPP
extern "C"
{
}
void main()
{
}
本文来自:http://blog.csdn.net/keensword/article/details/401114
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析extern
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- 解析“extern”
- SWT的TableVierer的使用一
- vc6.0Error spawning cl.exe错误的解决方法
- SWT的TableVierer的使用二(数据排序)
- C、C++笔记
- SWT的TableVierer的使用三(数据筛选和着色)
- 解析extern
- Eclipse常用热键
- io阻塞与io非阻塞之
- SWT的ListVierer的使用
- 数据库事务的隔离级别
- SWT的文件选择对话框I的使用
- 关于傅利叶变换的一些数学解…
- SWT的选择文件和文件夹的函数
- 解决win7没有找到suite objects.dll 因此rational rose不能能启动