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

时间:2016-11-02 21:19:32

标签: 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 ++需要强制内联其内联函数,即使它们已被装饰为具有隐藏的可见性?

1 个答案:

答案 0 :(得分:4)

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

当我创建libc ++时,我唯一的目标是macOS(OS X)。这是在libc ++开源之前的方式。强制内联的主要动机是控制将在OS版本中推出的dylib的ABI。强制内联函数永远不会出现在dylib中,因此我可以指望它专门生成一个标题(它具有与OS版本不同的传递系统)。

我从未考虑过"隐藏"的其他属性。作为这个决定的一部分,因为这对我来说只是一个不必要的复杂因素。我希望函数存在于头文件中,并且永远不会被放入dylib中,就是这样。所以你的第一颗子弹我认为是正确的。

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