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

          CSAPP - Linking - Strong and weak symbols

          Posted on 2007-08-02 23:45 ZelluX 閱讀(874) 評論(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則不會發出警告。
          主站蜘蛛池模板: 苗栗县| 遵义县| 苏尼特左旗| 土默特右旗| 河津市| 江西省| 镇平县| 中阳县| 会同县| 渝中区| 图木舒克市| 富源县| 越西县| 疏附县| 大庆市| 商城县| 古交市| 平谷区| 普洱| 金寨县| 宁武县| 青阳县| 呼伦贝尔市| 长垣县| 仙桃市| 邮箱| 阿图什市| 龙州县| 勃利县| 湛江市| 山阴县| 雅江县| 米泉市| 万全县| 东方市| 剑河县| 贵德县| 正定县| 霍林郭勒市| 怀集县| 麻城市|