为什么 libcxx 应用 __forceinline 或 GCC 等效于它已经隐藏的内联函数?
Why does libcxx apply __forceinline or the GCC equivalent to its already hidden inline functions?
我想确切地了解为什么内联函数的 libc++ 可见性宏使用 __forceinline
或 __attribute__((__always_inline__))
作为它与内联函数关联的属性的一部分。
背景见:
如果这些内联函数无论如何都将被标记为 __visibility__("hidden")
,为什么还需要强制编译器将它们内联?
我想了一下,我有一些假设,但 none 似乎完全令我满意:
- 是为了保证符号不会意外成为ABI的一部分。如果在构建库时,编译器选择不内联函数,它可能会成为外部符号,因此成为 ABI 的一部分。但是
hidden
属性还不够吗?同样,构建库时是否只需要强制内联函数?消费者不应该关心。
- 这是为了确保函数永远不会有定义,以避免 ODR 问题,编译器选择不在库本身中内联函数,并选择不在由 a 生成的代码中内联函数图书馆的客户,导致两个不同的定义。但这不是使用
visibility("hidden")
的预期(和可接受的)结果吗?
- 作为标准库的实现,它是 libc++ 设计的特定内容。
我问这个是因为我正在构建一个 C++ 库,我希望有一天能为此标准化 ABI,并且我正在使用 libc++ 作为指南。到目前为止,它运行良好,但是这个问题引起了一些挠头。
特别是,我们收到了用户抱怨 MSVC 拒绝遵守 __forceinline
属性的报告,这导致了警告。我们建议的解决方案是在构建库时将我们的类似物扩展到 INLINE_VISIBILITY 仅包括 __forceinline
(或 GCC 等价物),假设上面的第一个解释。
但是,由于我们并不完全有信心首先理解强制内联函数成为 __forceinline
或 __attribute__((__always_inline__))
背后的原因,因此我们对采用此解决方案有些犹豫。
谁能给出明确的答案,说明为什么 libc++ 觉得有必要强制内联其内联函数,即使它们已经被装饰为具有隐藏的可见性?
我可能是解决这个问题的最佳人选,因为我就是这样做的人。你可能不喜欢这个答案。 :-)
当我创建 libc++ 时,我唯一的目标是 macOS (OS X)。这是 libc++ open-sourced 之前的方式。我强制内联的主要动机是控制将随 OS 版本推出的 dylib 的 ABI。强制内联函数永远不会出现在 dylib 中,因此我可以指望它只存在于 header 中(它的传送系统与 OS 版本不同)。
我从未考虑过 "hidden" 的附加属性作为此决定的一部分,因为它对我来说只是一个不必要的并发症。我希望该函数存在于 header 中,并且永远不会被放入 dylib 中,仅此而已。所以我认为你的第一个项目符号是正确的。
我很高兴 libc++ 已经超越了它原来的范围,我希望你能继续努力。我很乐意提供我可能需要帮助您实现目标的任何其他信息。
我想确切地了解为什么内联函数的 libc++ 可见性宏使用 __forceinline
或 __attribute__((__always_inline__))
作为它与内联函数关联的属性的一部分。
背景见:
如果这些内联函数无论如何都将被标记为 __visibility__("hidden")
,为什么还需要强制编译器将它们内联?
我想了一下,我有一些假设,但 none 似乎完全令我满意:
- 是为了保证符号不会意外成为ABI的一部分。如果在构建库时,编译器选择不内联函数,它可能会成为外部符号,因此成为 ABI 的一部分。但是
hidden
属性还不够吗?同样,构建库时是否只需要强制内联函数?消费者不应该关心。 - 这是为了确保函数永远不会有定义,以避免 ODR 问题,编译器选择不在库本身中内联函数,并选择不在由 a 生成的代码中内联函数图书馆的客户,导致两个不同的定义。但这不是使用
visibility("hidden")
的预期(和可接受的)结果吗? - 作为标准库的实现,它是 libc++ 设计的特定内容。
我问这个是因为我正在构建一个 C++ 库,我希望有一天能为此标准化 ABI,并且我正在使用 libc++ 作为指南。到目前为止,它运行良好,但是这个问题引起了一些挠头。
特别是,我们收到了用户抱怨 MSVC 拒绝遵守 __forceinline
属性的报告,这导致了警告。我们建议的解决方案是在构建库时将我们的类似物扩展到 INLINE_VISIBILITY 仅包括 __forceinline
(或 GCC 等价物),假设上面的第一个解释。
但是,由于我们并不完全有信心首先理解强制内联函数成为 __forceinline
或 __attribute__((__always_inline__))
背后的原因,因此我们对采用此解决方案有些犹豫。
谁能给出明确的答案,说明为什么 libc++ 觉得有必要强制内联其内联函数,即使它们已经被装饰为具有隐藏的可见性?
我可能是解决这个问题的最佳人选,因为我就是这样做的人。你可能不喜欢这个答案。 :-)
当我创建 libc++ 时,我唯一的目标是 macOS (OS X)。这是 libc++ open-sourced 之前的方式。我强制内联的主要动机是控制将随 OS 版本推出的 dylib 的 ABI。强制内联函数永远不会出现在 dylib 中,因此我可以指望它只存在于 header 中(它的传送系统与 OS 版本不同)。
我从未考虑过 "hidden" 的附加属性作为此决定的一部分,因为它对我来说只是一个不必要的并发症。我希望该函数存在于 header 中,并且永远不会被放入 dylib 中,仅此而已。所以我认为你的第一个项目符号是正确的。
我很高兴 libc++ 已经超越了它原来的范围,我希望你能继续努力。我很乐意提供我可能需要帮助您实现目标的任何其他信息。