posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          CSAPP - Linking - Strong and weak symbols

          Posted on 2007-08-02 23:45 ZelluX 閱讀(871) 評論(0)  編輯  收藏 所屬分類: C/C++System
          《竊聽風暴》的男主角烏爾里希·穆埃(Ulrich Mühe) 病逝了。。。
          好片子,好演員,可惜了。。。

          CSAPP 第七章Linking太枯燥了  啃了半天總算看到一點實際經歷中遇到過的。

          在編譯階段,編譯器把全局變量標記為strong或者weak,并導出到匯編程序中,由匯編程序把這些信息隱式地添加到relocatable object file的符號表(symbol table)中。
          函數和被初始化的全局變量被標記為strong,未初始化的全局變量被標記為weak。
          Unix連接器(linker)使用下面的規則來處理多個符號的情況:
          1. 不允許多個strong symbol的存在
          2. 如果有一個strong symbol和若干個weak symbol,使用strong symbol
          3. 只有若干個weak symbol,則使用其中任意一個

          幾個例子(未特殊說明的情況,變量定義均在全局范圍):
          1. foo1.c和bar1.c中都有int main()方法,即存在了兩個strong symbol,連接器就會產生一條錯誤信息。
          2.
          /* foo3.c */
          #include 
          <stdio.h>
          void f(void);

          int x = 15213;

          int main()
          {
              f();
              printf(
          "x = %d\n", x);
              
          return 0;
          }

          /* bar3.c */
          int x;

          void f()
          {
              x 
          = 15212;
          }
          main()方法調用f()后,x變為15212并被輸出。
          注意這可能不是main()方法的作者原來的意圖。
          類似的情況也可能發生在兩個weak symbol同名的時候。

          3. 全局變量類型不同的情況:
          /* foo5.c */
          #include 
          <stdio.h>
          void f(void);

          int x = 15213;
          int y = 15212;

          int main()
          {
              f();
              printf(
          "x = 0x%x  y = 0x%x \n", x, y);
              
          return 0;
          }

          /* bar4.c */
          double x;

          void f()
          {
              x 
          = -0.0;
          }
          根據書上的內容,
          linux> gcc -o foobar5 foo5.c bar5.c
          linux> ./foobar5
          結果應該是
          x = 0x0  y = 0x80000000

          但是在自己機器上編譯時報錯了,可能連接器版本較高,會自動找出這種錯誤
          /usr/bin/ld: Warning: alignment 4 of symbol `x' in /tmp/ccupQXSG.o is smaller than 8 in /tmp/ccNNG9XZ.o
          是double和int大小不義導致的對齊問題


          這些問題都比較細小難以被查覺,通常在程序執行了一段時間后才出現較嚴重的問題,因此很難被修復,尤其當許多程序員不清楚連接器的工作方式的時候。
          另外可以使用GCC的-warn-common標記(flag),使得它在解析多個同名的全局變量時發出警告。
          試了下沒成功@@
          gcc --warn-common提示無法識別的命令行選項,gcc -Wall則不會發出警告。
          主站蜘蛛池模板: 渝中区| 蕲春县| 太白县| 横峰县| 盖州市| 枣强县| 安陆市| 永州市| 华坪县| 阜新| 彩票| 上林县| 张家川| 磴口县| 赣州市| 广平县| 奈曼旗| 汉川市| 繁峙县| 华容县| 临西县| 顺昌县| 吉安县| 道孚县| 阿勒泰市| 东台市| 进贤县| 黔江区| 江安县| 革吉县| 达州市| 丹寨县| 阳朔县| 乡城县| 大悟县| 邵武市| 沁水县| 井陉县| 玉溪市| 织金县| 嘉荫县|