为什么libcxx应用__forceinline或GCC等效于其已隐藏的内联函数?

acm*_*acm 8 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属性,从而导致警告.我们提出的解决方案是__forceinline在构建库时将模拟扩展到INLINE_VISIBILITY仅包括(或GCC等效),假设上面的第一个解释.

但是,由于我们并不完全相信我们理解强制内联函数背后的原因,__forceinline或者__attribute__((__always_inline__))首先,我们对采用这种解决方案有点犹豫不决.

任何人都可以提供一个明确的答案,为什么libc ++需要强制内联其内联函数,即使它们已被装饰为具有隐藏的可见性?

How*_*ant 4

我可能最适合解决这个问题,因为我是解决这个问题的人。你可能不喜欢这个答案。:-)

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

我从来没有考虑过“隐藏”的附加属性作为这个决定的一部分,因为这对我来说只是一个不必要的复杂化。我希望该函数位于标头中,而不是放入 dylib 中,就是这样。所以我认为你的第一颗子弹是正确的。

我很高兴 libc++ 已经超出了其最初的范围,并祝愿您在继续这一努力方面一切顺利。我很乐意提供任何可能有助于您实现目标的其他信息。