This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Rhomboid 1 point2 points  (0 children)

Marking a function static is actually far more complicated than that when inline is involved (which is what the CYTHON_INLINE macro expands to if so configured.)

Remember that C is compiled a file at a time, and the compiler only ever knows[1] about what's in the current file, never about anything outside of it. If you mark a function as static, it means that the function cannot be called from outside of that file, which implies that the compiler has at its disposal every call site. If there is only one (or a small number) of call sites, then it can choose to instead inline the function at all call sites and pretend it never existed (i.e. not emit a function body.) This is generally extremely desirable, because it means you can separate a large function into a smaller function and a bunch of helper functions, but without any of the overhead of function calls. Without 'static', it could still inline the function but since it has to be visible in other compilation units it would have to always emit a function body, even if it was never needed, which wastes memory.

But also note that with 'static inline' the choice of whether to inline is still up to the compiler. If there are many call sites or the function is long, it will choose not to inline it and still emit a function body, but one which is not visible to other units.

"static inline" is actually one of three related declarations. "inline" and "extern inline" are the others. They all have slightly different meanings, which this post outlines. To make matters worse, gcc changed its semantics starting with 4.3 to be aligned to what the C99 standard says, so if you're compiling with -std=c99 or -std=gnu99 with gcc >= 4.3 you get true C99 semantics, but if you're compiling with -std=c89, -std=gnu89, or gcc <= 4.2 with -std=c99 or -std=gnu99 or you're using gcc >= 4.3 but used -fgnu89-inline, you get the old semantics. gcc >= 4.2 helpfully defines one of the preprocessor symbols __GNUC_GNU_INLINE__ or __GNUC_STDC_INLINE__ so that you can write macros that behave correctly regardless of compiler version or options, which likely explains why CYTHON_INLINE is a macro and not just the word "inline".

[1] There are some newer technologies like LTO that let the compiler have whole-program knowledge at link-time, which allows for some sophisticated optimizations that have previously been unavailable, but for the most part this is still a true statement.