C inline all functions in source file - c

In my project I have some "Interface" functions which are defined in my header files. But I have much more functions which are only used internally in the same source file. So there is also no function declaration in any header file.
Is it good practice to declare them as inline? Since inline functions are better in performance it sounds like a good idea to me. Or are there any drawbacks? I know that the executable file might get larger in size but this is ok for me.

Local functions, not shared in different units of translations, should be qualified as static.
The inline specifier instructs compiler to inline the function if it can, but doesn't impose the inlining. If you require that the compiler inlines the function use forceinline, or __forceinline, to force the inlining.
Anyway when inlining functions consider that this is not always the best solution. You should carefully check the overall performance of your code. The inlining process merge the code of the function inside the calling code. This requires some register availability to perform calculation without disturbing the main execution. Sometime the process of register scooting requires temporary storage of current values or the like that could deteriorate the overall efficiency of code.
The inlining is beneficial when it is a short process and the time required for its execution inside main code is less than the time required for call prologue and epilogue.

Don't hesitate, just tag them as static inline as you want.
Note that a function marked inline is not necessary inline. It's left to the compilers to judge whether to make it inline. Modern compilers are "clever" enough, so simply let your compiler make its decision, which is trustworthy.

inline is just a hint to the compiler. If you specify inline the compiler may choose to not honour that hint. If you do not specify inline the compiler may choose to inline the function.
See 6.7.4 (p6) in the C11 Standard.

Related

Why is optimizing inline functions easier than normal functions?

Im reading What Every Programmer Should Know About Memory
https://people.freebsd.org/~lstewart/articles/cpumemory.pdf and it says that inline functions make your code more optimizable
for example:
Inlining of functions, in particular, allows the compiler to optimize larger chunks of code at a time which, in turn, enables the generation of machine code which better exploits the processor’s pipeline architecture
and:
The handling of both code and data (through dead code elimination or value range propagation, and others) works better when larger parts of the program can be considered as a single unit.
and this also:
If a function is only called once it might as well be inlined. This gives the compiler the opportunity to perform more optimizations (like value range propagation, which might significantly improve the code).
After reading these, to me atleast it seems like inline functions are easier to optimize, but why? Why is it easier to optimize something is inline?
The reason that it is easier to make a better job when optimizing inlined functions than with outlined is that you know the complete context in which the function is called and can use this information to tune the generated code to match this exact context. This often allows more efficient code for the inlined copy of the function but also for the calling function. The caller and the callee can be optimized to fit each other in a way that is not possible for outlined functions.
There is no difference!
All functions are subject to being inlined by gcc in -O3 optimization mode, whether declared inline, static, neither or both.
see: https://stackoverflow.com/a/40783656/9925764
or here is the modifying the example of #Eugene Sh. without noinline option.
https://godbolt.org/z/arPEf7rd4

Is there, as in JavaScript, a performance penalty for creating functions in C?

In JavaScript, there are, often, huge performance penalties for writing functions. For example, if you use this function:
function double(x){ return x*2; }
inside an inner loop, you are probably hitting your performance considerably, so it is really profitable to inline that kind of function for intensive applications. Does this, in general, hold for C? Am I free to create those kind of functions for everything, and rest assured the compiler will do the job, or is hand inlining still important?
The answer is: it depends.
I'm currently using MSVC compiler and GCC for a project at work and my experience is that they both do a pretty good job. Furthermore, the cost of a function call in native code can be pretty small, especially in functions that do not need to be accessible outside the executable (like functions not exported in a shared library). For these functions, there is more flexibility with how the call is actually implemented.
A few things to note: it's much easier for a compiler to optimize calls to static functions. Functions with external linkage often require link time optimization since one must know how and where the function is actually called, as well as the implementation, to do much optimization or inlining. This requires examining more than one compilation unit at a time.
I would say that you should use functions where it makes sense and makes the code easier to read and maintain. In general, it is safe to assume that the cost is smaller than it would be in JavaScript. But in the end, you'd have to profile the code to say anything more precise.
UPDATE: I want to emphasize that functions can be inlined across compilation units, but this requires link-time optimization (or whole program optimization). This is supported in both GCC (https://gcc.gnu.org/wiki/LinkTimeOptimization) and MSVC (http://msdn.microsoft.com/en-us/library/0zza0de8.aspx).
These days, if you can beat the compiler by copying the body of a function and pasting it everywhere you call that function, you probably need a different compiler.
In general, with optimizations turned on, gcc will tend to inline short functions provided that they are defined in the same compilation unit that they are called in.
Moreover, if the calling function and called function are in different compilation units, the compiler does not have a chance to inline them regardless of what you request.
So, if you want to maximize the chance of the compiler optimizing away a function call (without manually inlining), you should define the function call in .h file or in the same c file that it is called in.
There are no inner functions in C. Dot. So the rest of your question is kind of irrelevant.
Anyway, as of "normal" functions in C compiler may or may not inline them ( replace function invocation by its body ). If you compile your code with "optimize for size" it may decide to do not do inlining for obvious reason.

Difference between macros and functions in C in relation to instruction memory and speed

To my understanding the difference between a macro and a function is, that a macro-call will be replaced by the instruction in the definition, and a function does the whole push, branch and pop -thing. Is this right, or have I understand something wrong?
Additionally, if this is right, it would mean, that macros would take more space, but would be faster (because of the lack of the push, branch and pop instructions), wouldn't it?
What you are wrote about the performance implications is correct if the C compiler is not optimizing. But optimizing compilers can inline functions just as if they were macros, so an inlined function call runs at the same speed as a macro, and there is no pushing/popping overhead. To trigger inlining, enable optimization in your compiler settings (e.g. gcc -O2), and put your functions to the .h file as static inline.
Please note that sometimes inlining/macros is faster, sometimes a real function call is faster, depending on the code and the compiler. If the function body is very short (and most of it will be optimized away), usually inlining is faster than a function call.
Another important difference that macros can take arguments of different types, and the macro definition can make sense for multiple types (but the compiler won't do type checking for you, so you may get undesired behavior or a cryptic error message if you use a macro with the wrong argument type). This polymorphism is hard to mimic with functions in C (but easy in C++ with function overloading and function templates).
This might have been right in the 1980s, but modern compilers are much better.
Functions don't always push and pop the stack, especially if they're leaf functions or have tail calls. Also, functions are often inlined, and can be inlined even if they are defined in other translation units (this is called link-time optimization).
But you're right that in general, when optimizations are turned off, a macro be inlined and a function won't be inlined. Either version may take more space, it depends on the particulars of the macro/function.
A function uses space in two ways: the body uses space, and the function call uses space. If the function body is very small, it may actually save space to inline it.
Yes your understanding is right. But you should also note that, no type checking in macro and it can lead to side effect. You should also be very careful in parenthesizing macros.
Your understanding is half correct. The point is that macros are resolved before compilation. You should think of them as sophisticated text replacement tools (that's oversimplifying it, but is mostly what it comes down to).
So the difference is when in the build process your code is used.
This is orthogonal to the question of what the compiler really does with it when it creates the final binary code. It is more or less free to do whatever it thinks is correct to produce the intended behaviour. In C++, you can only hint at your preference with the inline keyword. The compiler is free to ignore that hint.
Again, this is orthogonal to the whole preprocessor business. Nothing stops you from writing macros which result in C++ code using the inline keyword, after all. Likewise, nobody stops you from writing macros which result in a lot of recursive C++ functions which the compiler will probably not be able to inline even if wanted to do.
The conclusion is that your question is wrong. It's a general question of having binaries with a lot of inlined functions vs. binaries with a lot of real function calls. Macros are just one technique you can use to influence the tradeoff in one way or the other, and you will ask yourself the same general question without macros.
The assumption that inlining a function will always trade space for speed is wrong. Inlining the wrong (i.e. too big) functions will even have a negative impact on speed. As is always the case with such opimisations, do not guess but measure.
You should read the FAQ on this: "Do inline functions improve performance?"

Alternatives to C "inline" keyword

From my course instructor, he has repeatedly emphasized and asked us not to use the "inline" keyword for functions. He says it is not "portable" across compilers and is not "standard". Considering this, are there any "standard" alternatives that allow for "inline expansion"?
Your course instructor is wrong. It is standard. It's actually in the current standard, right there in section 6.7.4 Function specifiers (C99). The fact that it's a suggestion to the compiler that may be totally ignored does not make it any less standard.
I don't think it was in C89/90 which may be what some embedded compilers use but I would give serious consideration to upgrading in that case.
However, even where inline is available, I generally leave those decisions up to the compiler itself since most modern ones are more than capable of figuring out how best to optimise code (and usually far better than I). The inline keyword, like register and auto, is not something I normally worry about at all.
You can use macros instead since that's relatively simple text substitution that generally happens before the compile phase but you should be aware of the limitations and foibles.
Or you can manually inline code (ie, duplicate it) although I wouldn't suggest this as an option since it may quickly become a maintenance nightmare.
Myself, I would write the code using normal functions without any of those tricks and then introduce them where necessary (and only if you can demonstrate that they're needed, such as a specific performance issue).
You should always assume that the coder who has to maintain your code is a psychopathic killer who knows where you live :-)
As others have said, inline was integrated to the C standard 11 years ago.
Other than was indicated, inline makes a difference since it changes the visibility properties of the function. In particular for large libraries with a lot of functions declared only static you might have one version of any these function in all object files (e.g when you compile with debugging switched on).
Please have a look into that post: Myth and reality about inline in C99
As evil as they may be, macros are still king (although specific compilers may support extra capabilities).
Here, now it's "portable across compilers":
#if (__STDC_VERSION__ < 199901L)
#define inline
#endif
static inline int foobar(int x) /* ... */
By the way, as others have said, the inline keyword is just a hint and rather useless, but the important keyword is static. Unless your function is declared static, it will have external linkage, and the compiler is unlikely to consider it a candidate for inlining when it makes its own decisions about which functions to inline.
Also note that unlike in C++, the C language does not allow inline without static.

C Inline Functions and Memory Use

If I use inline functions, does the memory usage increase?
There are two kinds of memory usage that inline functions will affect:
code size — in general, inlining code will increase how much memory is used to load your program. This is because there will be multiple copies of the generated code scattered around your program. However, this isn't always true -- if your inlined function was only used once, there's little change, and if the inlined function is very small, you could get a net reduction in code size by removing the function call overhead. Also, the function may be reduced in size by the optimizer that's able to remove code that's not used in the particular inline invocation.
stack usage — If your inlined functions have lots of local variables, then you may use more stack space. In C, the compiler usually allocates the stack space for a function once upon entry to the function. This has to be large enough to hold all the local variables that aren't stored in registers. If you call a function out-of-line, the stack for that function is used until it returns, when it's released again. If you inline the function, then that stack space will remain used for the whole life of the uber-function.
Inlining won't affect heap usage, as the same allocations and deallocations would occur for the inlined code as would occur for the non-inlined version.
There is another point you have to consider:
Using inline functions, the compiler is able to see where variables of the caller are going to be used as variables in the callee. The compiler can optimize out (often this is really many assembler lines that can be omitted. look out for the so called "aliasing problem") redundant code based on that knowledge. So your "code bloat" is often not all that big, especially if you have smaller functions it can even reduce bloat as Jim stated above.
Someone made a good point: Better make the compiler decide whether it inlines the function in question or not, since it knows the code it generates better than you ever would.
Depends on the function. Simple one-liners could have a memory reduction since no callstack needs to be setup and cleaned and no function call is made. If the function is larger than this overhead needed to call a function, then it will of course bloat the code.
That is really un-answerable in the general case.
To start with you do not generally have control over the in-lining. Even if you mark a function inline it is actually still up to the compiler wither it will actually do the in-lining (it is just a hint).
The compiler will do its best to optimize the code; using in-lining is just one tool in doing this. So inlining short functions will make the code smaller (as you don't need to set up the parameters for the call or retrieve the return value. But even with long functions the answer is not absolute.
If the compiler decides to inline a long function then you would think the code would get longer. But this is not generally the case; as this gives the compiler extra opportunities to apply other optimization techniques that could potentially make the code still smaller. If the compilers analysis finds that the resulting code bloat is detrimental to the code the in-lining will not be done.
Basically the compiler does its analysis and decides and the best course of action.
Conclusion. Don't worry about it. The compiler is smarter than you and will do the correct thing.
Inline functions definitely increase the size of your final executable(or binary), because they will be "copy-pasted" whereever you call them.
You program will in the general case become larger (I'm sure there are exceptions, though). The runtime memory consumption might go down, but not by much.
Why are you asking? Normally, you let the compiler determine whether a function should be inlined or not; it can usually make a better call given the size and complexity of the function.
A function call requires several processor instructions.
You usually need a PUSH instruction for every argument to the function, a CALL instruction to call the function, and often another instruction that cleans up the stack after the function call.
Also, functions may modify the processor's registers, so the calling function may need more instructions to preserve registers or reload values that would otherwise still be in registers.
So if the function you're calling is just a few instructions long, inlining it can save memory and run faster.
That said, inlining is for when your profiler tells you that you should.
It sometimes so happens that we have functions scattered all over the program.In this case a function call causes the program to jumps to the address of the function and come back when the function call terminates. This takes away some precious time.
The above problem can be resolved with the use of inline functions. This causes the compiler to call the code directly from the source. No new memory instruction set is created for the inline function code.
Although the inline declaration in c++ is free and occurs automatically when the function is defined in the declaration, in c it is restricted by the following rules ::
In C, any function with internal linkage can be declared inline, but a function with external linkage is has restrictions on inline.
If the inline keyword is used in the function declaration, then the function definition should be present in the same translation unit.
inline datatype function_name(arguments)
This code runs upto 30% fastert than a non inline function, the rest depending on the prcessor speed.
Now comes the strategy part. You may use inline functions at your will but keeping in mind that inline functions can take much less time to execute but they have a high memory occupancy on the run. Also the compiler has always an option to overlook your inline declaration if the code declared inline is abnormally large compared to the code size.
Inline declaration although destroys the order of evaluation, does not make the function internal. The function is still external.

Resources