1. 程式人生 > >const變數定義於標頭檔案中

const變數定義於標頭檔案中

一。、首先要知道強弱符號

編譯器編譯原始檔時會把原始檔的全域性符號(global symbol)分成強(strong)和弱(weak)兩類傳給彙編器,
    而隨後彙編器則將強弱資訊編碼並儲存在目標檔案的符號表中。
    那麼何謂強弱呢?編譯器認為函式與初始化了的全域性變數都是強符號,而未初始化的全域性變數則成了弱符號。

比如有這麼個原始檔:
extern int errorno;
int buf[2] = {1,2};
int *p;
int main()
{
   return 0;
}

其中main、buf是強符號,p是弱符號,而errorno則非強非弱,因為它只是個外部變數的使用宣告。
有了強弱符號的概念,我們就可以看看連結器是如何處理與選擇被多次定義過的全域性符號:
規則1: 不允許強符號被多次定義(即不同的目標檔案中不能有同名的強符號);
規則2: 如果一個符號在某個目標檔案中是強符號,在其它檔案中都是弱符號,那麼選擇強符號;
規則3: 如果一個符號在所有目標檔案中都是弱符號,那麼選擇其中任意一個;

二、然後來看這個問題

C/C++code
/* headerer.h */

#ifndef HEADER_H_
#define HEADER_H_

#include <stdio.h>

const int X = 10;

void func1(void);
void func2(void);

#endif




C/C++ code
/* file1.c */

#include "headerer.h"

void func1(void)
{
    printf("This is file1. X =%d\n", X);
    return;
}




C/C++ code
/* file2.c */

#include "headerer.h"

void func2(void)
{
    printf("This is file2. X =%d\n", X);
    return;
}




C/C++ code
/* main.c */
#include "headerer.h"

int main()
{
    printf("This is main. X =%d\n", X);
    func1();
    func2();
    
    return 0;
}




在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語言可以支援多個弱符號。