静态函数和具有"隐藏"可见性属性的函数之间的实际区别是什么?

Ale*_*ing 14 c visibility

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

我觉得这些改变方式的方式并不完全相同,但我不知道在实际代码中使用它们时有什么区别,也不知道它是什么意思.两者之间有什么变化,什么时候你想用另一个?

Bas*_*tch 15

一个函数__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函数可以更容易内联,或者编译器可以(有时)为它使用不同的调用约定.


Ani*_*nge 5

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

例如:

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

__attribute__((visibility("hidden"))) void foo() {}
Run Code Online (Sandbox Code Playgroud)

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