I'd like to understand exactly why the libc++ visibility macro for an inline function uses __forceinline
or __attribute__((__always_inline__))
as part of the attributes it associates with inline functions.
For background see:
If these inline functions are going to be marked as __visibility__("hidden")
anyway, why is it necessary to additionally force the compiler to inline them?
I've thought about it a bit, and I have a few hypotheses, but none seems entirely satisfactory to me:
- It is to ensure that the symbol does not accidentally become part of the ABI. If, while building the library, the compiler chose not to inline the function, it could potentially become an external symbol, and therefore part of the ABI. But wouldn't the
hidden
attribute be sufficient? Similarly, wouldn't it only be necessary to force inline the function when building the library? Consumers shouldn't care. - It is to ensure that the function never has a definition, to avoid ODR issues, where the compiler choses not to inline the function in the library itself, and choses not to inline in the function in the code generated by a client of the library, resulting in two different definitions. But isn't that an expected (and accepted) outcome of using
visibility("hidden")
? - It is something specific to the design of libc++ as an implementation of the standard library.
I ask this because I'm working on building a C++ library for which I hope to someday standardize an ABI, and I'm using libc++ as a guide. So far, it has worked well, but this issue has caused some head scratching.
In particular, we have had reports of users complaining that MSVC has refused to honor the __forceinline
attribute, leading to warnings. Our proposed solution is to have the expansion of our analogue to INLINE_VISIBILITY only include __forceinline
(or the GCC equivalent) when building the library, assuming the first explanation above.
However, since we aren't entirely confident that we understand the reasoning behind forcing inline functions to be __forceinline
or __attribute__((__always_inline__))
in the first place, we are somewhat hesitant to adopt this solution.
Can anyone provide a definitive answer for why libc++ feels the need to force inline its inline functions, even though they are already decorated as having hidden visibility?