在C和C++中,符号可见性是指 对象和函数在不同组件(例如动态链接库或共享库)之间的可见程度。
__attribute__((visibility("hidden")))
是GCC/Clang提供的一种机制,用于控制符号的可见性,以
提高代码安全性和优化链接性能。
符号可见性
符号可见性主要有以下几种类型:
-
默认可见性(默认,default):
- 通常情况下,编译器生成的符号是默认可见的。这意味着这些符号可以在其他库或程序中被引用。
- 例如:
void my_function() { // 函数体 }
-
隐藏可见性(hidden):
- 使用
__attribute__((visibility("hidden")))
声明符号为隐藏,不允许其他模块访问这个符号。有助于避免名称冲突,以及减少外部模块对内部实现的依赖。 - 例如:
void my_hidden_function() __attribute__((visibility("hidden")));
- 隐藏符号不会出现在生成的动态库的符号表中。
- 使用
-
保护可见性(protected):
- 这种可见性允许符号在派生类中可见,但在其他模块中不可见。这通常用于类中的虚函数。
- 例如:
class MyClass { protected: virtual void my_protected_function(); };
-
内部可见性(internal):
- 符号只能在定义它的共享库内部可见,其他模块无法访问。比如static修饰
__attribute__((visibility("hidden")))
使用 通过将符号的可见性设置为隐藏,可以实现以下目标:
-
防止名称冲突:
- 当多个库中有同名符号时,隐藏可防止外部引用,从而避免链接时的名称冲突。
-
减少二进制体积:
- 隐藏未使用的符号可以减少生成的库的符号表大小,从而在一定程度上减小二进制文件的体积。
-
安全性:
- 隐藏内部实现细节,可以降低外部程序对库的非预期依赖,提高安全性。
示例
以下是一个简单示例,展示了如何使用 __attribute__((visibility("hidden")))
:
// my_library.c
__attribute__((visibility("hidden"))) void my_hidden_function() {
// 内部实现,不希望被外部访问
}
void my_public_function() {
// 可以被外部访问
}
在生成的共享库中,my_hidden_function
不会出现在符号表中,而 my_public_function
会被公开。
结论
通过配置符号的可见性,可以控制哪些符号在不同模块间可见,从而优化库的结构和提高安全性。使用 __attribute__((visibility("hidden")))
是实现这一目标的有效手段。