【问题标题】:Why does libcxx apply __forceinline or the GCC equivalent to its already hidden inline functions?为什么 libcxx 应用 __forceinline 或 GCC 等价于其已经隐藏的内联函数?
【发布时间】:2016-11-02 21:19:31
【问题描述】:

我想确切地了解为什么内联函数的 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++ 觉得有必要强制内联其内联函数,即使它们已经被装饰为具有隐藏的可见性?

【问题讨论】:

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


    【解决方案1】:

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

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

    我从未将“隐藏”的附加属性视为此决定的一部分,因为这对我来说只是不必要的复杂情况。我希望该函数存在于标题中,并且永远不会被放入 dylib 中,就是这样。所以我认为你的第一个项目符号是正确的。

    我很高兴 libc++ 已经超出了其最初的范围,并祝您继续努力。我很乐意提供任何其他信息来帮助您实现目标。

    【讨论】:

    • 我很喜欢这个答案,感谢您花时间回复。听起来我们可能可以继续重新评估我们对 __forceinline 的货物崇拜是否不必要并且应该被删除。听起来很可能。此外,如果您有兴趣了解我们正在采用的方法或提供任何反馈,那么有问题的库是 libmongocxx:github.com/mongodb/mongo-cxx-driver/tree/master
    猜你喜欢
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多