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

相关文章
相关标签/搜索