c++ - 为什么 libcxx 应用 __forceinline 或 GCC 等效于它已经隐藏的内联函数?

标签 c++ dll shared-libraries abi libc++

我想确切地理解为什么内联函数的 libc++ 可见性宏使用 __forceinline__attribute__((__always_inline__)) 作为它关联的属性的一部分内联函数。

背景见:

如果这些内联函数无论如何都将被标记为 __visibility__("hidden"),为什么还需要额外强制编译器将它们内联?

我想了一下,我有一些假设,但似乎没有一个让我完全满意:

  • 这是为了确保符号不会意外成为 ABI 的一部分。如果在构建库时,编译器选择不内联函数,它可能会成为外部符号,因此成为 ABI 的一部分。但是 hidden 属性还不够吗?同样,构建库时是否只需要强制内联函数?消费者不应该关心。
  • 这是为了确保函数永远不会有定义,以避免 ODR 问题,编译器选择不在库本身中内联函数,并选择不在客户端生成的代码中内联函数图书馆,导致两个不同的定义。但这不是使用 visibility("hidden") 的预期(和可接受的)结果吗?
  • 它是 libc++ 设计的特定内容,作为标准库的实现。

我问这个是因为我正在构建一个 C++ 库,我希望有一天能为此标准化 ABI,并且我正在使用 libc++ 作为指南。到目前为止,它运行良好,但这个问题引起了一些挠头。

特别是,我们收到了用户提示 MSVC 拒绝遵守 __forceinline 属性的报告,这导致了警告。我们建议的解决方案是在构建库时,将我们的类似 INLINE_VISIBILITY 的扩展仅包含 __forceinline(或 GCC 等效项),假设上面的第一个解释。

但是,由于我们并不完全有信心首先理解强制内联函数为 __forceinline__attribute__((__always_inline__)) 背后的原因,我们对采用这个解决方案有些犹豫。

谁能给出明确的答案,说明为什么 libc++ 觉得有必要强制内联其内联函数,即使它们已经被装饰为具有隐藏的可见性?

最佳答案

我可能是解决这个问题的最佳人选,因为我就是这样做的人。你可能不喜欢这个答案。 :-)

当我创建 libc++ 时,我唯一的目标是 macOS (OS X)。这是在 libc++ 开源之前的方式。我强制内联的主要动机是控制将随操作系统版本推出的 dylib 的 ABI。强制内联函数永远不会出现在 dylib 中,因此我可以指望它只存在于 header 中(它具有与操作系统版本不同的交付系统)。

我从来没有考虑过“隐藏”这个附加属性作为这个决定的一部分,因为它对我来说只是一个不必要的并发症。我希望该函数位于 header 中,永远不会放入 dylib 中,仅此而已。所以我认为你的第一个项目符号是正确的。

我很高兴 libc++ 已经超越了它原来的范围,我希望你能继续努力。我很乐意提供我可能需要帮助您实现目标的任何其他信息。

关于c++ - 为什么 libcxx 应用 __forceinline 或 GCC 等效于它已经隐藏的内联函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40389994/

相关文章:

c++ - 无法从 SFML 实现纯虚函数

c++ - 是什么导致无法在 DWARF perf 调用堆栈中展开?

c++ - C 共享对象,带有 C++ 存档、静态 Ctors/Dtors 和 dlopen

delphi - Delphi中exe和DLL之间的TobjectList

linux - 如何链接共享库的特定名称(版本)

c - 我怎么知道我的 .so 库的足迹?

c++ - 寻找数组中的平衡点

c++ - 在 C++ 中将一个 int 打包到一个位域中

c# - 无法加载 DLL 'sqlite3' : The specified module could not be found

c++ - 在 win32 c++ 中,有没有办法判断 DLL 是否为 64 位?