程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C與C++對於全局變量的不同處理之處

C與C++對於全局變量的不同處理之處

編輯:C++入門知識

下面看看我犯的錯誤:
    當時寫了一個類似於下面的枚舉:
 
    #ifndef TEST_ENUM_H_
 
    #define TEST_ENUM_H_
 
    enum {
 
    TEST_FLAG1_E,
 
    TEST_FLAG2_E,
 
    TEST_FLAG_NR
 
    } TEST_E;
 
    #endif
 
    當時在enum關鍵字前面遺漏了“typedef”。我一般習慣於使用typedef,這樣可以直接使用TEST_E而不是enum TEST_E。
 
    該頭文件會被其它源文件引用。由於在代碼中,沒有需要定義枚舉變量的地方,只是使用枚舉的值,所以當時沒有發現遺漏“typedef”。編譯也沒有任何問題。
 
    但是當天的build卻沒有通過。錯誤信息顯示定義了重復的TEST_E,因此編譯失敗。由於與美國的時差問題,這個錯誤由美國的一同事修改了。他陳述的錯誤原因是:這樣的枚舉聲明對於C來說,是沒有問題的。——我們的核心代碼都是C編寫的。
 
    但是對於C++,會認為不是聲明而是定義,定義了一個TEST_E變量。結果導致重復定義了該變量。——有一部分web功能代碼是使用C++編寫的。
 
    當我早上看到他的說明時,首先要對break build表示歉意;第二也鄙視了一下該產品的makefile——我剛剛加入這個產品組。這樣的makefile,為了檢查checkin,我不得不先make clean才能保證所有的代碼被編譯。這樣花費的時間太多了。第三,我才想起web的這部分功能是使用C++的。第四,寒一下自己,居然漏寫了typedef;第五,也有些好奇C++的編譯為什麼出錯。
 
    但是當我看到他的陳述時,我知道他肯定錯了。對於C和C++來說,枚舉enum的區別不會這麼大。對於上面那個枚舉類型定義,由於遺漏了typedef,所以這裡的TEST_E無論是C還是C++來說,都會把TEST_E當作一個枚舉變量處理,也就是一個全局變量。那麼引起問題的原因是因為C和C++對於沒有初始值的全局變量的處理不同——真拗口,而最後的編譯鏈接行為不同。
 
    看下面的簡單示例:
 
    文件test1.c
 
    int a;
 
    int main()
 
    {
 
    return 0;
 
    }
 
    文件tes2.c
 
    int a;
 
    編譯
 
    [fgao@fgao-vm-fc13 test]$ gcc -g -Wall test1.c test2.c
 
    [fgao@fgao-vm-fc13 test]$
 
    編譯沒有任何的warning和error。對於沒有初始值的全局變量,其為弱符號。對於多個弱符號定義,在C的鏈接階段不會有任何問題。大家可以參見我這篇文章通過未初始化全局變量,研究BSS段和COMMON段的不同:http://www.BkJia.com/kf/201202/118030.html
 
    在這篇文章中,我解釋了為什麼C允許多個弱符號存在
 
    下面將其視為C++代碼,使用g++編譯:
 
    [fgao@fgao-vm-fc13 test]$ g++ -g -Wall test1.c test2.c
 
    /tmp/ccQdTwRi.o:(。bss+0x0):multiple definition of `a'
 
    /tmp/cc7SOWD1.o:/home/fgao/works/test/test1.c:4: first defined here
 
    collect2: ld returned 1 exit status
 
    同樣是沒有初始值的全局變量,在C++的鏈接階段就會報錯。對於C++為什麼報錯,這肯定是由於C++的鏈接機制有關。目前我並不清楚原因,有了解的朋友請賜教。謝謝。

摘自 十分愛的博客

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved