__attribute__
是一個編譯器指令,其實是 GNU C
的一種機制,本質是一個編譯器的指令,在聲明的時候可以提供一些屬性,在編譯階段起作用,來做多樣化的錯誤檢查和高級優化。
用于在 C
,C++
,Objective-C
中修飾變量、函數、參數、方法、類等。
合理使用 __attribute__
有什么好處?
- 給編譯器提供上下文,幫助編譯器做優化,合理使用可以收到顯著的優化效果。
-
編譯器會根據
__attribute__
產生一些編譯警告,使代碼更規范。 - 給代碼閱讀者提供必要的注解,助其理解代碼意圖。
總之,__attribute__
起到了給編譯器提供上下文的作用,如果錯誤的使用 __attribute__
指令,因為給編譯器提供了錯誤的上下文,由此引起的錯誤通常很難被發現。
強符號和弱符號
在同一作用域下不能定義同一個變量或函數,很多C語言學習者都理所當然地這么認為。
這個其實是是有所偏頗的,GNU C對標準C語言進行了擴展,在GCC中,對于符號(在編譯時,變量和函數都被抽象成符號)而言,存在著強符號和弱符號之分。
是的,是否支持這個特性是由不同的C語言標準決定的。
對于C/C++而言,編譯器默認函數和已初始化的全局變量為強符號,而未初始化的全局變量為弱符號。
在編程者沒有顯示指定時,編譯器對強弱符號的定義會有一些默認行為,同時開發者也可以對符號進行指定,使用"attribute((weak))"來聲明一個符號為弱符號。
定義一個相同的變量,當兩者不全是強符號時,gcc在編譯時并不會報錯,而是遵循一定的規則進行取舍:
-
當兩者都為強符號時,重復定義的報錯:
redefinition of 'xxx'
- 當兩者為一強一弱時,選取強符號的值
- 當兩者同時為弱時,選擇其中占用空間較大的符號,這個其實很好理解,編譯器不知道編程者的用意,選擇占用空間大的符號至少不會造成諸如溢出、越界等嚴重后果。
在默認的符號類型情況下,強符號和弱符號是可以共存的,類似于這樣:
intx;
intx=1;
編譯不會報錯,在編譯時x的取值將會是1.
注意,這里可以使用__attribute__((weak))
將強符號轉換為弱符號,卻不能與一個強符號共存,類似于這樣:
int__attribute__((weak))x=0;
intx=1;
編譯器將報重復定義錯誤。
強引用和弱引用
除了強符號和弱符號的區別之外,GNUC還有一個特性就是強引用和弱引用。
我們知道的是,編譯器在編譯階段只負責將源文件編譯成目標文件(即二進制文件),然后由鏈接器對所有二進制文件進行鏈接操作。
編譯器默認所有的變量和函數為強引用,同時編程者可以使用__attribute__((weakref))
來聲明一個函數。
注意這里是聲明而不是定義,既然是引用,那么就是使用其他模塊中定義的實體,對于函數而言,我們可以使用這樣的寫法:
__attribute__((weakref))voidfunc(void);
,然后在函數中調用func()
,如果func()
沒有被定義,則func
的值為0,如果func
被定義,則調用相應func,在《程序員的自我修養》這本書中有介紹,它是這樣寫的:
__attribute__((weakref))voidfunc(void);
voidmain(void)
{
if(func){func();}
}
但是在現代的編譯系統中,這種寫法卻是錯誤的,編譯雖然通過(有警告信息),但是卻不正確:
warning:‘weakref’attributeshouldbeaccompaniedwithan‘alias’attribute[-Wattributes]
警告顯示:weakref需要伴隨著一個別名才能正常使用
強/弱符號和強/弱引用的作用
這種弱符號、弱引用的擴展機制在庫的實現中非常有用。
我們在庫中可以使用弱符號和弱引用機制,這樣對于一個弱符號函數而言,用戶可以自定義擴展功能的函數來覆蓋這個弱符號函數。
同時我們可以將某些擴展功能函數定義為弱引用,當用戶需要使用擴展功能時,就對其進行定義,鏈接到程序當中。
如果用戶不進行定義,則鏈接也不會報錯,這使得庫的功能可以很方便地進行裁剪和組合。
注意:C標準里根本沒有提到強、弱符號。這只是GCC這個實現定義的特性,在MS C編譯器里是不存在這個概念的。
審核編輯 :李倩
-
C語言
+關注
關注
180文章
7630瀏覽量
140207 -
函數
+關注
關注
3文章
4367瀏覽量
64159 -
編譯器
+關注
關注
1文章
1654瀏覽量
49880
原文標題:C語言進階小技巧,弱符號和弱引用
文章出處:【微信號:knifewheat,微信公眾號:小麥大叔】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
芯盾時代用戶身份和訪問管理平臺助力企業消滅弱口令
景嘉微榮獲2024湖南湘江新區民營企業“稅收貢獻百強”“研發投入百強”“社會責任百強”稱號
繼電器的作用及常用類型介紹
snmp弱口令及安全加固
普強榮獲2024智能客服企業TOP20
中科創達榮登北京民營企業百強和科技創新百強榜單
適合弱可燃(A2L)制冷劑檢測的氣體傳感器模塊FCM2630
C語言與其他編程語言的比較
普強成功榮登兩大榜單
請問弱信號前放輸出如何使用并聯放大器分為兩路?
電機弱磁時的電流大小關系?
宋仕強論道之深圳華強北

其利天下技術·無刷電機弱磁控制是什么?有什么好處·BLDC驅動方案

評論