关于C++仅头文件库符号可见性的疑问(Clang 15.0.6)
Clang 15.0.6下C++符号可见性问题解答
问题1:共享库A.so的符号可见性
当使用-fvisibility=hidden编译共享库A.so时,所有未显式指定可见性的符号默认可见性为hidden,而非默认对外可见。具体来说:
- 标记
__attribute__((hidden))的foo():可见性为hidden,不会被导出到A.so的符号表中 - 未标记的
bar():受全局默认规则影响,可见性同样是hidden,也不会被导出到符号表
因此,链接A.so的共享库B.so既无法调用foo(),也无法调用bar()。如果希望bar()能被外部调用,需要显式标记它为__attribute__((visibility("default")))。
问题2:仅头文件库的inline函数符号可见性
仅头文件库C是INTERFACE类型,意味着它的代码会被直接编译进链接它的共享库D.so中。结合-fvisibility=hidden编译选项:
- 标记
__attribute__((hidden))的inline函数xxx():即使编译器未将其内联、生成了外部符号,该符号的可见性也是hidden,不会导出到D.so的符号表 - 未标记的inline函数
yyy():受-fvisibility=hidden的默认规则约束,可见性同样为hidden,生成的符号也不会被导出
另外,C++中的inline函数如果被编译器成功内联,D.so中根本不会生成对应的外部符号,E.so自然无法直接调用;即便未被内联,由于符号是hidden状态,E.so也无法引用这些符号。
因此,链接D.so的共享库E.so既无法调用xxx(),也无法调用yyy()。如果希望inline函数能被外部调用,需要显式标记它为__attribute__((visibility("default"))),同时可配合__attribute__((noinline))避免被完全内联(但这不符合inline函数的设计初衷,需谨慎使用)。
内容的提问来源于stack exchange,提问作者bourne
相关产品推荐
相关产品推荐

