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:
hidden
attribute be sufficient? Similarly, wouldn't it only be necessary to force inline the function when building the library? Consumers shouldn't care.visibility("hidden")
?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?
I'm probably in the best position to address this as I'm the one who did it. And you may not like the answer. :-)
When I was creating libc++ my only target was macOS (OS X). This was way before libc++ was open-sourced. And my main motivation for forcing inline was to control the ABI of the dylib that would be pushed out with OS releases. A forced inline function would never appear in a dylib, and thus I could count on it living exclusively in a header (which had a different delivery system than OS releases).
I never considered the additional attribute of "hidden" as part of this decision because it was simply an unnecessary complication for me. I wanted the function to live in a header, and never be put into a dylib and that was that. So your first bullet is I believe correct.
I am thrilled that libc++ has grown beyond its original scope and I wish you the best in continuing that effort. I'm happy to supply any additional information I might have to aid you in your goal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With