Why is libcxx using __forceinline or GCC equivalent to already hidden built-in functions?

I would like to understand exactly why the libC ++ visibility macro for an inline function uses __forceinline or __attribute__((__always_inline__)) as part of the attributes that it associates with inline functions.

For background see

If these built-in functions are marked as __visibility__("hidden") in any case, why is it necessary to additionally force the compiler to embed them?

I thought about this a bit, and I have several hypotheses, but no one seems completely satisfactory to me:

  • This means that the symbol does not accidentally become part of the ABI. If, when creating the library, the compiler decided not to embed the function, it could potentially become an external symbol and, therefore, part of the ABI. But will the hidden attribute suffice? In the same way, is it only necessary to force a function to be included when building a library? Consumers don't care.
  • This means that a function never has a definition in order to avoid ODR problems when the compiler does not want to embed the function in the library and does not want to embed the function in the code created by the library client, which leads to two different definitions. But isn't this the expected (and accepted) result of using visibility("hidden") ?
  • This is something specific to the design of libC ++ as an implementation of the standard library.

I ask about this because I am working on a C ++ library for which I hope to someday standardize ABI, and I use libC ++ as a guide. So far, it worked well, but this problem caused some head scratches.

In particular, we had reports that users complained that MSVC refused to comply with the __forceinline attribute, which leads to warnings. Our proposed solution is to expand our analogue with INLINE_VIBIBITY to include only __forceinline (or the GCC equivalent) when building the library, assuming the first explanation above.

However, since we are not completely sure that we understand why the built-in functions are primarily forced to be __forceinline or __attribute__((__always_inline__)) , we are hesitant to make this decision.

Can someone give a definitive answer for why lib ++ feels the need to force its built-in functions to be forced, even if they are already decorated as hidden visibilities?

+8
c ++ dll abi shared-libraries libc ++
source share
1 answer

I am probably in a better position to address this since I am the one who did it. And you may not like the answer. :-)

When I created libC ++, my only goal was macOS (OS X). This was before libC ++ was open source. And my main motivation for forcing inline is to control the ABI Dilib, which will be superseded by OS versions. A forced built-in function will never be displayed in dylib, and so I could expect it to live exclusively in the header (which had a different delivery system than the OS releases).

I never considered the additional attribute β€œhidden” as part of this solution, because it was just an extra complication for me. I wanted the function to live in the header and never be put in dylib, and that was so. So, your first bullet, I believe, is true.

I am very pleased that libC ++ has grown beyond its original scope, and I wish you all the best in continuing this effort. I am happy to provide any additional information that may help you in your goal.

+4
source share

All Articles