- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我是想看看我的理解是否正确。
inline
是对 C++ 编译器的建议,只要它认为更好,就替换一个函数,因此从库外部调用标记为内联的过程不可靠,它们在逻辑上应该被隐藏默认情况下,阻止其他人调用它们作为对编译器或代码库的更新可以改变决定(因此删除 inline
d 函数和 ABI 破坏?)。
然而,这似乎不是默认设置,应该设置 -fvisibility-inlines-hidden
来实现这一点。我在这里问为什么会这样?没有任何实际用例的设置,它只是因为遗留原因而存在吗?
最佳答案
they logically should be hidden by default
C++ 要求所有函数(包括 inline
函数)在所有翻译单元中具有相同的地址。本地静态信息也应该在所有翻译单元之间共享。如果程序构建为多个共享对象(.so 文件),则隐藏内联函数违反了这些要求。
内联函数应该具有公共(public)可见性,以便动态链接器可以在运行时从所有现有定义中选择一个定义。
海湾合作委员会 wiki提到这个:
-fvisibility-inlines-hidden
can be used with no source alterations, unless you need to override it for inlines where address identity is important either for the function itself or any function local static data.
考虑以下示例。可执行源:
// main.cpp
#include <cstdio>
struct A { };
inline A &foo()
{
static A a;
return a;
}
int main()
{
void *p = &foo();
std::printf("main() - %p\n", p);
}
共享对象来源:
#include <cstdio>
struct A { };
inline A &foo()
{
static A a;
return a;
}
static __attribute__((constructor)) void init()
{
void *p = &foo();
std::printf("main() - %p\n", p);
}
如果您针对此共享对象构建并链接可执行文件,您会看到 foo
始终在两个翻译单元中返回相同的地址。
现在,如果您将 __attribute__((visibility("hidden")))
添加到这些内联函数中,那么您将看到地址在不同的翻译单元中是不同的。
这不是某些 C++ 程序可能期望的。
今天大多数人认为 inline
与实际的函数内联无关。这不完全正确。 ELF 目标试图使动态链接透明,例如如果程序被构建为单个可执行文件或多个共享对象,则其行为应该相同。
为了使其成为可能,ELF 要求通过 GOT 或通过 PLT 调用所有具有公共(public)可见性的函数,就好像它是“导入”函数一样。这是必需的,以便每个函数都可以被另一个库(或可执行文件本身)覆盖。这也禁止内联所有公共(public)非内联函数(参见第 3.5.5 节 here,其中表明 PIC 中的公共(public)函数调用应通过 PLT 进行)。
公共(public)内联函数的代码内联是可能的,因为 inline
允许在多个内联函数定义不等价时程序行为未定义。
有趣的注意事项:Clang 违反了这个 ELF 要求,并且无论如何都能够在 ELF 目标上内联公共(public)函数。 GCC 可以使用 -fno-semantic-interposition
标志来做同样的事情。
关于c++ - 为什么 `-fvisibility-inlines-hidden` 不是默认值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48621251/
我对 C++ 可见性属性有疑问。我已阅读 http://gcc.gnu.org/wiki/Visibility但我不太明白它是如何工作的。 我想在我拥有的一些共享库中隐藏可见性。我相信这意味着符号被隐
我有一个共享库项目,它是由 4 个静态库 ( .a ) 和一个对象 ( .o ) 文件构建的。我正在尝试添加 -fvisibility=hidden选项将输出中的符号限制为仅我在源中使用 __attr
我正在构建一个共享对象 (.so),并将其链接到第三方静态库。在理想情况下,该第三方库应该使用 -fvisibility=hidden 进行编译 - 但事实并非如此。 有没有办法避免在动态库导出的全局
我正在构建一个启用了 GCC_INLINES_ARE_PRIVATE_EXTERN 和 GCC_SYMBOLS_PRIVATE_EXTERN 的项目,因为我正在使用预先构建的带有这些标志的静态库。 但
我有一个 A 类: class A { public: A() {} virtual ~A() {} void Func(); }; 和另一个使用 A 的 M 类。我想创建 libM
我有一个共享库,它应该只导出一个标有 __attribute__ ((visibility ("default"))) 的函数。 .它还与另一个静态库 (fftw) 链接,并且 #include 前面
我是想看看我的理解是否正确。 inline 是对 C++ 编译器的建议,只要它认为更好,就替换一个函数,因此从库外部调用标记为内联的过程不可靠,它们在逻辑上应该被隐藏默认情况下,阻止其他人调用它们作为
我们面临与 OpenSSL 静态链接的共享库的问题。该库用于 Apache HTTP Server。虽然我们已经使用 OpenSSL 静态编译了我们的共享库,但它使用的是系统 OpenSSL 库路径,
我用 C++ 开发了跨平台软件。据我所知,Linux .so默认导出所有符号,通过 "gcc -fvisibility=hidden" 我可以将所有导出的符号设置为隐藏,然后设置 __attribut
我需要使用 -fvisibility=hidden 编译 openssl 代码以隐藏大量符号,然后在 Xcode 中使用。使用下面的 GitHub 链接。我可以获得 libssl.a 和 libcry
来自 https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Optimize-Options.html#index-fsemantic-interposition
我正在尝试在 Cygwin 的测试程序中使用 Phonon 库。 CMake 用于构建: find_package(Phonon REQUIRED) 但它会生成以下错误消息: $ make -- Fo
这是我在 Mac OS X 上使用 clang++ 时遇到的问题的缩小版本。经过认真编辑,以更好地反射(reflect)真正的问题(描述问题的第一次尝试没有表现出问题)。 失败 我有一个 C++ 软件
我是一名优秀的程序员,十分优秀!