__attribute__((visibility("visibility_type")))
當咱們並不但願暴露一個方法時,通常狀況使用static
關鍵字來修飾函數。這樣編譯時該方法就不會被輸出到符號表裏。詳細可參見這篇博文html
LLVM和GCC其實也提供了相似的attribute
segmentfault
使用示例:模塊化
__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
既然說到了visibility,那順帶說一下這個flag,這個flag在調用gcc或者llvm時指定。表示編譯時的對全部方法的默認visibility的選擇(除非顯式指定方法的visibility)。htm
-fvisibility=default|internal|hidden|protected
blog
通常來講隱藏方法使用static
就夠了。但此attribute爲大型工程項目提供了一種可能性,便可以使某些模塊總體隱藏全部接口,只暴露特別指定的方法。接口
此外gcc的編譯器還能夠像以下這樣使用:
#pragma GCC visibility push(hidden) void method1() {...} void method2() {...} ... #pragma GCC visibility pop
即表示在push
與pop
之間聲明的全部方法,其可見性都按照指定的進行編譯。
這個關鍵字也有static相同的做用
經過上述提供的幾種手段,在一些複雜模塊化的大中型項目中,咱們能夠更加靈活地對不一樣模塊進行可行性的控制,可以更精細對項目進行模塊化,而且減小符號被覆蓋的風險。
還有一些有趣的attribute,之後再寫
objc_root_class
objc_designated_initializer
naked
原做寫於segmentfault 連接