__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 连接