18

我知道在函数上使用staticC 中的关键字会将函数限制为定义它的编译单元。我现在正在研究符号可见性,我对static函数和用 标记的函数__attribute__((visibility("hidden")))或使用-fvisibility=hidden命令行选项之间的区别有点困惑。

我有一种感觉,这些在幕后改变事物的方式根本不一样,但我不知道区别是什么,也不知道在实际代码中使用它们时意味着什么。两者之间有什么变化,您什么时候想使用其中一个?

4

3 回答 3

17

一个函数__attribute__((visibility("hidden")))在包含它的共享库之外是不可见的,但是如果该库是通过链接创建的foo.pic.o,并且bar.pic.o这样的函数fhid可以在 中定义foo.c和调用bar.c。当然外部代码(例如来自主程序或其他共享库)不能调用它fhid

因此,隐藏可见性适用于整个共享库,而不适用于组成它的单个编译单元。

相比之下,foo.c定义一个static void fsta(void)函数和bar.c定义一个不同 static void fsta(void)的函数是可能的(即使这很糟糕,出于可读性的原因应该避免这样做)。

此外,原则上,一个static函数可以更容易地内联,或者编译器可以(有时)为它使用不同的调用约定。

于 2013-02-17T09:04:07.830 回答
5

如果您在共享库中有一个global函数,您只想在共享库的上下文中使用,而不是在共享库之外使用 - 那么您需要__attribute__((visiblity("hidden")))

例如:

如果您在其中void foo()定义了一个函数Foo.c并且您希望它引用它Bar.c以及Baz.c要生成哪些编译单元FooBarBaz.dll(或 FooBarBaz.so),那么您可以将该函数设为

__attribute__((visibility("hidden"))) void foo() {}

请记住,加载(或 .so 文件)foo()的可执行文件将不可见阅读本文dll

于 2013-02-17T09:11:30.110 回答
0

隐藏可见性表示该符号不会被放入动态符号表中,因此没有其他“模块”(可执行文件或共享库)可以直接引用它。

http://ohse.de/uwe/articles/gcc-attributes.html

我可以补充:您可以__attribute__((visibility("hidden")))在 C++ 中使用语义接近 C 版本的static.

于 2013-02-17T09:06:26.510 回答