一。、首先要知道強弱符號
編譯器編譯原始檔時會把原始檔的全域性符號(global symbol)分成強(strong)和弱(weak)兩類傳給彙編器,
而隨後彙編器則將強弱資訊編碼並儲存在目標檔案的符號表中。
那麼何謂強弱呢?編譯器認為函式與初始化了的全域性變數都是強符號,而未初始化的全域性變數則成了弱符號。
比如有這麼個原始檔:
extern int errorno;
int buf[2] = ;
int *p;
int main()
其中main、buf是強符號,p是弱符號,而errorno則非強非弱,因為它只是個外部變數的使用宣告。
有了強弱符號的概念,我們就可以看看鏈結器是如何處理與選擇被多次定義過的全域性符號:
規則1: 不允許強符號被多次定義(即不同的目標檔案中不能有同名的強符號);
規則2: 如果乙個符號在某個目標檔案中是強符號,在其它檔案中都是弱符號,那麼選擇強符號;
規則3: 如果乙個符號在所有目標檔案中都是弱符號,那麼選擇其中任意乙個;
二、然後來看這個問題
c/c++code
/* headerer.h */
#ifndef header_h_
#define header_h_
#include
const int x = 10;
void func1(void);
void func2(void);
#endif
c/c++ code
/* file1.c */
#include "headerer.h"
void func1(void)
c/c++ code
/* file2.c */
#include "headerer.h"
void func2(void)
c/c++ code
/* main.c */
#include "headerer.h"
int main()
在vc6.0中,由上述4個檔案(headerer.h, file1.c, file2.c, main.c)組成的工程為什麼編譯報錯?
但如果將file1.c, file2.c, main.c三個檔名改為file1.cpp, file2.cpp, main.cpp,其他不變的情況下卻可以正確執行。
為什麼啊?難道c和c++差異很大嗎?記得在c++中,用const宣告的變數具有內部連線性,因此上述改為.cpp的工程可以正月編譯並執行。c語言中難道不是這樣嗎?
答案:c++中const預設為定義他的檔案的區域性變數,而c中認為是extern的量。但是在c中若constint x = 10; 把「=10」去掉。 那也可以編譯成功了,因為這些定義都是弱符號,c語言可以支援多個弱符號。
標頭檔案中定義變數
在標頭檔案中定義了乙個變數,若另乙個檔案再 int 變數名 則會再產生乙個相同變數的定義,在linux環境中編譯時會發生如 menu.o sbss 0x0 multiple definition of is refresh living time thread created main.o sbss...
關於const物件定義在標頭檔案中
摘自 c primer 4nd 一些const物件定義在標頭檔案中。而const變數要成為常量表示式,初始化式必須為編譯器可見。為了能夠讓多個檔案使用相同的值,const變數和它的初始化式必須是每個檔案可見的。而要使初始化式可見,一般把這樣的const變數定義在標頭檔案中。那樣的話,無論該const...
標頭檔案中定義 const 全域性變數應注意的問題
我們知道,在 c 但不是在 c 語言 中,const 限定符對預設儲存型別稍有影響。在預設情況下,全域性變數的鏈結性為外部的,但 const 全域性變數的鏈結性為內部的。也就是說,在 c 看來,全域性 const 定義就像使用了 static 說明符一樣。因此,可以將 const 常量定義在標頭檔案...