亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

舉例講解C語言鏈接器的符號解析機制

2020-01-26 14:34:37
字體:
來源:轉載
供稿:網友

1. 符號分類
(1)全局符號:非靜態全局變量,非靜態函數
(2)外部符號:定義于其它模塊,而被本模塊引用的全局變量和函數
(3)本地符號:靜態變量(包括全局和局部),靜態函數
對于靜態局部變量,編譯器會為其生成唯一的名字。如x.fun1,x.fun2。本地符號對鏈接器來說是不可見的。
2. 符號決議
當編譯器遇到一個不是本模塊定義的符號時,會假設該函數由其它模塊定義,并生成一個鏈接器符號表條目,交由鏈接器處理。如果鏈接器在它的任何輸入模塊都沒有找到該符號,會給出一個類似undefined reference to 'xxx'的鏈接錯誤。而如果鏈接器在輸入模塊中找到了一個以上的外部符號定義,這個時候就需要鏈接器進行符號決議,鏈接器對多個外部符號定義可能并不報錯甚至警告,而是按照它的規則去選擇其中一個符號定義。
鏈接器將各個模塊輸出的全局符號,分類為強符號和弱符號:
(1)強符號:函數和已初始化的全局變量
(2)弱符號:為初始化全局變量
根據強弱符號的定義,鏈接器按照下面的規則處理多重定義的符號:
規則1:不允許有多個強符號定義
規則2:如果有一個強符號和多個弱符號,那么選擇強符號
規則3:如果有多個弱符號,那么從這些弱符號中選擇sizeof大的那個,如果大小相同,則選擇先鏈接的那個
上面的規則是很多鏈接錯誤的根源,因為編譯器在決議時可能默默地替你作出了決定,你并不知曉。根據上面的規則,可以引出下面幾個經典例子:
例1:

// in lib1.cint x;void f(){  x = 1235;}// in main1.c#include<stdio.h>void f(void);int x = 1234;int main(void){  f();  printf("x=%d/n", x);  return 0;}

上面的代碼中,main函數printf輸出: x=1235。因為鏈接器通過規則2決議符號x的定義為main.c中的強符號定義,而lib.c的作者并不知情,他對x的使用和修改影響到了main.c。這種交互修改,相互影響將會很復雜,因為大家都以為自己在做對的事情,在用對的變量。而整個決議過程,鏈接器悄無聲息地完成了。
例2:

// in lib2.cdouble x;void f(){  x = -0.0;}// in main2.c#include<stdio.h>void f(void);int x = 1234;int y = 1235;int main(){  f();  printf("x=0x%x y=0x%x /n", x, y);  return 0;}

這種情況下,程序得到輸出: x=0x0 y=0x80000000,而鏈接器(gcc ld)也終于給出一條警告:

復制代碼 代碼如下:

ld: warning: tentative definition of '_x' with size 8 from 'obj/Debug/lib2.o' is being replaced by real definition of smaller size 4 from 'obj/Debug/main2.o'


鏈接器決議的是符號地址,而相鄰的全局變量可能在.data段中的內存地址也相鄰,因此也就引發了更復雜的問題。這一點和棧溢出很像,但是比棧溢出更復雜,因為問題出在多個模塊之間,而不是在一個函數內部。
例3:

// in lib3.cstruct{  int a;  int b;} x;void f(){  x.a = 123;  x.b = 456;  printf("in f(): sizeof(x)=%d, (&x)=0x%08x/n", sizeof(x), &x);}// in main3.c#include<stdio.h>void f(void);int x;int y;int main(){  f();  printf("in main(): sizeof(x)=%d, (&x)=0x%08x, (&x)=0x%08x, x=%d,y=%d /n", sizeof(x), &x, &y, x, y);  return 0;}

程序輸出:

in f(): sizeof(x)=8, (&x)=0x02489018in main(): sizeof(x)=4, (&x)=0x02489018, (&y)=0x02489020, x=123,y=0

始終記住,外部符號決議的是地址,因此無論lib3.c和main3.c中,符號x地址都是唯一的,無論其被定義了幾次。其次sizeof是編譯器決議,與鏈接無關,編譯器只看得到本模塊的定義或聲明。最后,由于符號x決議到lib3.c中的x,其size是8,因此main3.c中的y的地址比x大8,這是由鏈接器將lib3.o和main3.o合并后填入可執行文件的.data段的。因此y是無關變量,被初始化為0,注意和例2的區別。
3. 總結
由于符號決議容易引發的種種問題,我們在寫C的時候應注意:
盡量用static屬性隱藏變量和函數在模塊內的聲明,就像在C++中盡量用private保護類私有成員一樣。
少定義弱符號,盡量初始化全局變量,這樣鏈接器會根據規則1給出多個符號定義的錯誤。
為鏈接器設置必要選項,如gcc的 -fno-common,這樣在遇到多重符號定義時,鏈接器會給出警告。
4. C++的符號決議
C++并不支持強弱符號同時存在,所有符號都只能有一個定義(函數重載通過改寫函數符號來確保其唯一),因此在很大程度上避免了C中的鏈接器困擾。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久av在线看| 国产欧美日韩丝袜精品一区| 91麻豆国产语对白在线观看| 日韩视频第一页| 欧美日韩国产综合新一区| 91精品国产高清久久久久久| 久久久久成人精品| 久久久久这里只有精品| 亚洲最新av在线网站| 亚洲精品永久免费| 国产精品久久久久久网站| 久久免费视频在线观看| 日本成熟性欧美| 国产精品自产拍在线观看中文| 国产mv免费观看入口亚洲| 清纯唯美亚洲综合| 国产精品三级网站| 久久综合九色九九| 亚洲人免费视频| 欧美日韩激情视频8区| 亚洲人成网7777777国产| 第一福利永久视频精品| 日韩av手机在线看| 久久亚洲国产成人| 日本中文字幕久久看| 日日骚av一区| 亚洲欧美国产视频| 久久久久久久97| 久久精品在线视频| 日韩美女av在线免费观看| 欧美福利视频网站| 欧美黄色三级网站| 亚洲成人av资源网| 亚洲国产精品99久久| 欧美最猛黑人xxxx黑人猛叫黄| 精品久久久久久国产91| 久久久免费电影| 欧美国产第二页| 91极品女神在线| 亚洲精品欧美极品| 国产成人aa精品一区在线播放| 欧美一级成年大片在线观看| 国产在线精品播放| 国产一区视频在线| 成人h视频在线观看播放| 亚洲精品视频免费| 秋霞av国产精品一区| 国产午夜精品久久久| 精品国产欧美一区二区三区成人| 欧美性xxxx极品高清hd直播| 黑丝美女久久久| 亚洲全黄一级网站| 亚洲黄色免费三级| 亚洲性线免费观看视频成熟| 精品视频在线播放| 美女久久久久久久| 久久久亚洲欧洲日产国码aⅴ| 78m国产成人精品视频| 国产精品爽爽ⅴa在线观看| 日韩成人激情影院| 久久成人18免费网站| 国产精品男人爽免费视频1| 欧美大片免费观看在线观看网站推荐| 2019中文字幕在线免费观看| 欧美激情精品久久久久| 精品国产区一区二区三区在线观看| 欧美三级欧美成人高清www| 久久久久久久久久久网站| 成人免费激情视频| 亚洲老板91色精品久久| 精品日韩视频在线观看| 久久av.com| 成人免费观看a| 国产91精品久久久久久久| 情事1991在线| 国产精品久久久久久久久粉嫩av| 欧美成人激情在线| 神马久久桃色视频| 亚洲欧美一区二区激情| 美女福利视频一区| 丁香五六月婷婷久久激情| 亚洲精品电影在线观看| 久久国产精品久久久久久久久久| 久久久久久国产精品三级玉女聊斋| 国产a级全部精品| 亚洲图片在线综合| 久久香蕉国产线看观看av| 欧美精品日韩三级| 国产欧美亚洲精品| 国产精品91久久| 国产精品99蜜臀久久不卡二区| 亚洲伊人第一页| 日韩一区二区三区在线播放| 欧美日韩免费看| www国产91| 亚洲成人在线视频播放| 韩国精品美女www爽爽爽视频| 亚洲视频欧洲视频| 亚洲第一区第一页| 精品日韩美女的视频高清| 555www成人网| 青青在线视频一区二区三区| 91欧美精品午夜性色福利在线| 成人激情在线播放| 久久艳片www.17c.com| 亚洲精品中文字幕av| 热久久这里只有精品| 97视频在线观看视频免费视频| 日韩av在线网| 久久五月天综合| 欧美午夜精品伦理| 欧美日在线观看| 韩国三级日本三级少妇99| 热久久这里只有精品| 欧美激情视频一区二区三区不卡| 成人国产精品一区二区| 91高潮在线观看| 欧美成年人在线观看| 欧美限制级电影在线观看| 欧美一区二粉嫩精品国产一线天| 欧美交受高潮1| 久久91亚洲精品中文字幕奶水| 在线成人中文字幕| 亚洲精品自拍第一页| 国产剧情日韩欧美| 国产精品免费久久久久影院| 国外成人免费在线播放| 中文字幕在线观看日韩| 久久久久久久av| 日韩有码在线观看| 日韩美女视频中文字幕| 一区二区在线免费视频| 麻豆精品精华液| 免费91麻豆精品国产自产在线观看| 欧美一级免费看| 亚洲级视频在线观看免费1级| 成人国产在线激情| 欧美成人性色生活仑片| 国产精品爽黄69天堂a| 9.1国产丝袜在线观看| 国产精品第二页| 国产精品揄拍一区二区| 超碰91人人草人人干| 欧美性受xxxx黑人猛交| 欧美日本啪啪无遮挡网站| 日韩av在线影视| 久久国产精品影视| 久久6免费高清热精品| 亚洲欧美另类在线观看| 日韩精品极品在线观看播放免费视频| 国产一区香蕉久久| 精品久久久久久亚洲精品| 精品久久久香蕉免费精品视频| 国产免费亚洲高清| 国产精品av免费在线观看| 情事1991在线| 久久久999国产精品| 亚洲一区二区国产| 狠狠干狠狠久久| 国产精品∨欧美精品v日韩精品| 日韩欧美一区二区三区久久| 成人黄色片在线| 亚洲男子天堂网| 成人黄色在线免费|