天天看點

extern及extern C的作用

extern 作用1:聲明外部變量

現代編譯器一般采用按檔案編譯的方式,是以在編譯時,各個檔案中定義的全局變量是

互相透明的,也就是說,在編譯時,全局變量的可見域限制在檔案内部。

例1:

建立一個工程,裡面含有A.cpp和B.cpp兩個簡單的C++源檔案:

//A.cpp:

int iRI;

int main()

{

//.....

}

//B.cpp

gcc A.cpp -c

gcc B.cpp -c

編譯出A.o, B.o都沒有問題。

但當gcc A.o B.o -o test時,

main.o:(.bss+0x0): multiple definition of `iRI'

b.o:(.bss+0x0): first defined here

報錯:重定義。

(但有個非常意外的發現:當同樣的代碼,使用A.c B.c.并使用gcc編譯時,竟然不會報重定義的錯誤,非常不明白是怎麼回事。)

這就是說,在編譯階段,各個檔案中定義的全局變量互相是透明的,編譯A時覺察不到B中也定義了i,同樣,編譯B時覺察不到A中也定義了i。

但是到了連結階段,要将各個檔案的内容“合為一體”,是以,如果某些檔案中定義的全局變量名相同的話,在這個時候就會出現錯誤,也就是上面提示的重複定義的錯誤。是以,各個檔案中定義的全局變量名不可相同。

但如果用下列方式:在B.cpp中定義iRI;在A.cpp中直接使用。則編譯A.cpp時就無法通過。

//A.cpp

iRI=64;

was not declared in this scope.

原文出自:http://blog.csdn.net/songjinshi/article/details/6785267

因為編譯器按照檔案方式編譯,是以編譯A.cpp時,并不知道B.cpp中定義了iRI。

也就是說:檔案中定義的全局變量的可見性擴充到整個程式是在連結完成之後,而在編譯階段,他們的可見性仍局限于各自的檔案。

解決方案如下:

編譯器的目光不夠長遠,編譯器沒有能夠意識到,某個變量符号雖然不是本檔案定義的,但是它可能是在其它的檔案中定義的。

雖然編譯器不夠遠見,但是我們可以給它提示,幫助它來解決上面出現的問題。這就是extern的作用了。

extern的原理很簡單,就是告訴編譯器:“你現在編譯的檔案中,有一個辨別符雖然沒有在本檔案中定義,但是它是在别的檔案中定義的全局變量,你要放行!”

extern int iRI;

iRI = 64;

這樣編譯就能夠通過。

extern int iRI; //并未配置設定空間,隻是通知編譯器,在其它檔案定義過iRI。

extern 作用2:在C++檔案中調用C方式編譯的函數

C方式編譯和C++方式編譯

相對于C,C++中新增了諸如重載等新特性。是以全局變量和函數名編譯後的命名方式有很大差別。

int a;

int functionA();

對于C方式編譯:

int a;=> _a

int functionA(); => _functionA

對于C++方式編譯:

int a; =>xx@xxx@a

int functionA(); => xx@xx@functionA

可以看出,因為要支援重載,是以C++方式編譯下,生成的全局變量名和函數名複雜很多。與C方式編譯的加一個下劃線不同。

于是就有下面幾種情況:

例2:C++調用C++定義的全局變量

上一篇: extern