i've been messing around with compiler explorer and in C if i pass a function pointer to a static inline function to another function inside the same translation unit then both msvc and gcc seem to inline the static inline function's body

my question is, how much can i rely on this behavior?

@eniko it’s a quite reliable performance optimization, if you want to make it actually guaranteed you can use __attribute__((always_inline)) (for clang/gcc) and __forceinline (for msvc)
@porglezomp isn't that for when you're calling them directly, not as function pointers?

@eniko oh right right my bad. 😅 Overapplied things I was reading lately.

It’s still reliable enough through function pointers in the same translation unit that I know this approach is a code style some people have been recommending for years. If the function you’re passing the pointers to is large and is called enough times with different arguments the compiler might stop specializing it/inlining it.

@eniko

I would check the language spec. Optimizations can be compiler specific unless they are actually defined as part of the language itself. Even then, not all compilers may comply and some defined optimizations are still advisory ("register," for example).

Not that you don't have a good reason for this, but my own experience has been that I haven't found a need to shepherd a compiler for optimizations at that level for decades.

@eniko depends if you're fine with only supporting compilers with this optimisation, though generally it isn't exactly a complex one to have, so for you, i think it's fine to rely on

@eniko IME, it will stop doing that in MSVC at some small nesting level.

Useful macros:

#if _MSC_VER > 0
#define INLINE __forceinline
#else
#define INLINE __attribute__((always_inline)) inline
#endif

@eniko it's not 100% reliable (especially in MSVC), but there are ways to make it more reliable. MSVC has [[msvc::flatten]] or [[msvc::forceinline_calls]] (C++ only probably but then MSVC sucks for C so its usually better to compile as C++ anyway). And clang also supports `always_inline` on call statements and not just on declarations. For GCC I think the best bet is to use __attribute__((flatten)) on the calling function.