Playing with __attributes__ (三)

visibility

__attribute__((visibility("visibility_type")))
當咱們並不但願暴露一個方法時,通常狀況使用static關鍵字來修飾函數。這樣編譯時該方法就不會被輸出到符號表裏。詳細可參見這篇博文html

LLVM和GCC其實也提供了相似的attributesegmentfault

使用示例:模塊化

__attribute__((visibility("default"))) void foo1(int x, int y);
__attribute__((visibility("hidden"))) int foo2(int x);
__attribute__((visibility("protected"))) void foo3(int x, int y);
  • default意味着該方法對其餘模塊是可見的。函數

  • hidden代表該方法符號不會被放到動態符號表裏,因此其餘模塊(可執行文件或者動態庫)不能夠經過符號表訪問該方法。(但在運行時使用函數指針可對其進行調用,visibility是個編譯時的特性,正如你在運行時能夠修改const修飾的變量同樣).net

  • protected則表示該方法將會被放置到動態符號表,對其餘模塊可見。但該符號對其所在模塊是綁定的,即其餘模塊不可重載該符號。指針

  • internal,跟hidden類似。除非特別指定,不然意味着不能從模塊調用該方法。code

-fvisibility

既然說到了visibility,那順帶說一下這個flag,這個flag在調用gcc或者llvm時指定。表示編譯時的對全部方法的默認visibility的選擇(除非顯式指定方法的visibility)。htm

-fvisibility=default|internal|hidden|protectedblog

通常來講隱藏方法使用static就夠了。但此attribute爲大型工程項目提供了一種可能性,便可以使某些模塊總體隱藏全部接口,只暴露特別指定的方法。接口

其餘

此外gcc的編譯器還能夠像以下這樣使用:

#pragma GCC visibility push(hidden)
void method1() {...}
void method2() {...}
...
#pragma GCC visibility pop

即表示在pushpop之間聲明的全部方法,其可見性都按照指定的進行編譯。

private_extern

這個關鍵字也有static相同的做用

總述

經過上述提供的幾種手段,在一些複雜模塊化的大中型項目中,咱們能夠更加靈活地對不一樣模塊進行可行性的控制,可以更精細對項目進行模塊化,而且減小符號被覆蓋的風險。

llvm參考文檔

還有一些有趣的attribute,之後再寫

  • objc_root_class

  • objc_designated_initializer

  • naked

原做寫於segmentfault 連接

相關文章
相關標籤/搜索