inlining a function - c

I am developing in C using gcc in Linux.
I am organizing my small functions in .H and .C files in the following way
// .H file
extern int my_function( int val );
// .C file
inline int my_function( int val ){
// my job..very short!
}
These functions are small so they are very good candidates to be inlined but I don't know if they will be for sure.
I have doubt about the way I cam organizing my file and I was thinking that probably it would be better to have all my functions inlined directly into the .h file without .C file.
Can you help me a bit in clarifying my doubt?

First of all, note that you can tell gcc to try and inline small functions into their callers by adding the -finline-functions option.
If you have any doubt that your function will actually be inlined, you can ask gcc to warn you about uninlinable function, by using -Winline
Here, as your functions are declared both extern and inline, they will be inlined as the inline definition will only be used for inlining. In this particular situation the function will not be compiled on its own at all.
Read http://gcc.gnu.org/onlinedocs/gcc/Inline.html for further details.

No matter how small your function is, the choice is compiler's whether or not to inline it.
So even if you have very few number of functions and you inline them all in your code, there's still no guarantee that all will be inlined by the compiler.
You can find some useful inshgts on inlining here.

First, the compiler must be able to see the definition of a function in order to inline it. Hence, you must place the definition in the header file. (Here, I'm assuming your application consists of more than one source file). Note: Some development environments support multi-file compilation, in which case this remark does not apply.
Secondly, the semantics of inline C99 is a bit confusing if you are accustomed C++ (where things "just work"). In C99, you must single out a single source file (not header file) which own the function -- in case the function is not inlined in some source file, there must exist exactly one explicit definition of the function. This is done by specifying the function using the extern keyword. (This is a deviation from the traditional interpretation of extern, that it was used for declarations only).
For example:
// .h file
inline int my_function( int val )
{
// my job..very short!
}
// In ONE .c file
extern int my_function( int val );

Related

Benefits and drawbacks of making all functions in main.c static?

I have heard that, when you have just 1 (main.c) file (or use a "unity build"), there are benefits to be had if you make all your functions static.
I am kind of confused why this (allegedly) isn't optimized by default, since it's not probable that you will include main.c into another file where you will use one of its functions.
I would like to know the benefits and dangers of doing this before implementing it.
Example:
main.c
static int my_func(void){ /*stuff*/ }
int main(void) {
my_func();
return 0;
}
You have various chunks of wisdom in the comments, assembled here into a Community Wiki answer.
Jonathan Leffler noted:
The primary benefit of static functions is that the compiler can (and will) aggressively inline them when it knows there is no other code that can call the function. I've had error messages from four levels of inlined function calls (three qualifying “inlined from” lines) on occasion. It's staggering what a compiler will do!
and:
FWIW: my rule of thumb is that every function should be static until it is known that it will be called from code in another file. When it is known that it will be used elsewhere, it should be declared in a header file that is included both where the function is defined and where it is used. (Similar rules apply to file scope variables — aka 'global variables'; they should be static until there's a proven need for them elsewhere, and then they should be declared in a header too.)
The main() function is always called from the startup code, so it is never static. Any function defined in the same file as an unconditionally compiled main() function cannot be reused by other programs. (Library code might contain a conditionally compiled test program for the library function(s) defined in the source file — most of my library code has #ifdef TEST / …test program… / #endif at the end.)
Eirc Postpischil generalized on that:
General rule: Anytime you can write code that says the use of something is limited, do it. Value will not be modified? Make it const. Name only needs to be used in a certain section? Declare it in the innermost enclosing scope. Name does not need to be linked externally? Make it static. Every limitation both shrinks the window for a bug to be created and may remove complications that interfere with optimization.

In C, should inline functions in headers be externed in the .c file?

I've seen a few questions addressing this general topic, but I'm still unsure exactly what the correct approach is for ISO C, and how that may or may not vary from GNU C.
If I have some function inline void foo() in file.h defined with the inline keyword, should I also declare that function in file.c as extern void foo();? Assume that multiple .c files will include file.h.
From what I've read the answer seems to be "yes" and have something to do with how the compiler looks for definitions emitted by other translation units, but to be honest I don't fully understand the implications.
I'm working on a project right now that has a lot of functions declared inline within the header files, and none of those functions are declared in the corresponding .c files. Everything compiles without gcc complaining, but is this approach actually correct?
Yes, if you use inline without static, there needs to be an actual external definition of the function somewhere in case the compiler declines to inline it in one or more places. The canonical way to do that is to make a source file containining (using your example names) nothing but:
#include "file.h"
extern void foo();
Personally, I find extern inline semantics in C confusing and messy, and prefer to avoid them entirely by making all inline functions static. Of course this wastes space with multiple instantiations of the function if the compiler declines to inline, but you should not be doing this with functions of nontrivial size anyway.
inline means the compiler will expand that function where it is used in the code (instead of calling it as a function). That means that an inline definition in a header file with the function implementation in a .c file makes no sense, as wherever you include the header in another .c file the function can't be expanded inline as its code implementation is not known.
So you should keep the inline function and its code implementation in the header file.

static inline functions in a header file

Lately I have been making an attempt to read more open source C code. A common pattern that I have been adopting in my hobby projects is as follows.
In my C files, I have functions that are either static or exported. Only functions that are exported are placed in a header file. Global variables which are only used within the scope of an object are also used as static global variables.
My question concerns the usefulness and motivation of having static inline functions inside header files. From what I read online, not using the static keyword causes a multiple definition error and that is the reason for not just defining the function as just inline.
However, does this mean that this function is exported for other objects to use?
If yes, then why not just defining this function in the C file and export it via the header file?
If not, why putting this in the header file rather than just having it inside the C file?
Is there a reason behind this coding style? What am I missing?
One such example can be found in the git codebase inside hashmap.h:
/*
* Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code
* for use in hash tables. Cryptographic hashes are supposed to have
* uniform distribution, so in contrast to `memhash()`, this just copies
* the first `sizeof(int)` bytes without shuffling any bits. Note that
* the results will be different on big-endian and little-endian
* platforms, so they should not be stored or transferred over the net.
*/
static inline unsigned int sha1hash(const unsigned char *sha1)
{
/*
* Equivalent to 'return *(unsigned int *)sha1;', but safe on
* platforms that don't support unaligned reads.
*/
unsigned int hash;
memcpy(&hash, sha1, sizeof(hash));
return hash;
}
A static inline function is, in practice, likely (but not certain) to be inlined by some good optimizing compiler (e.g. by GCC when it is given -O2) at most of its call sites.
It is defined in a header file, because it then could be inlined at most call sites (perhaps all of them). If it was just declared (and simply "exported") the inlining is unlikely to happen (except if you compile and link with link-time optimizations, a.k.a. LTO, also, e.g. compile and link with gcc -flto -O2, and that increases a lot the build time).
In practice, the compiler needs to know the body of a function to be able to inline it. So a suitable place is to define it in some common header file (otherwise, it could be inlined only in the same translation unit defining it, unless you enable LTO), so that every translation unit would know the body of that inlinable function.
It is declared static to avoid multiple definitions (at link time) in case the compiler did not inline it (e.g. when you use its address).
In practice, in C99 or C11 code (except with LTO, which I rarely use), I would always put the short functions I want to be inlined as static inline definitions in common header files.
Be sure to understand how and when the C preprocessor works. Notice that you could in principle (but it would be very bad practice and disgusting style) avoid defining some static inline function in a common header file and instead copy and paste its identical definition in multiple .c files.
(However, that might make sense for generated .c files, e.g. if you design a compiler emitting C code).
FYI LTO is practically implemented by recent GCC compilers by embedding some internal compiler representation (some GIMPLE) inside object files, and redoing some "compilation" step - using the lto1 frontend - at "link" time. In practice, the entire program is almost compiled "twice".
(actually, I always wondered why the C standardization committee did not decide instead that all explicitly inline functions are static)

"inline" directive doesn't work (Pure C) [duplicate]

I defined my function in .c (without header declaration) as here:
inline int func(int i) {
return i+1;
}
Then in the same file below I use it:
...
i = func(i);
And during the linking I got "undefined reference to 'func'". Why?
The inline model in C99 is a bit different than most people think, and in particular different from the one used by C++
inline is only a hint such that the compiler doesn't complain about doubly defined symbols. It doesn't guarantee that a function is inlined, nor actually that a symbol is generated, if it is needed. To force the generation of a symbol you'd have to add a sort of instantiation after the inline definition:
int func(int i);
Usually you'd have the inline definition in a header file, that is then included in several .c files (compilation units). And you'd only have the above line in exactly one of the compilation units. You probably only see the problem that you have because you are not using optimization for your compiler run.
So, your use case of having the inline in the .c file doesn't make much sense, better just use static for that, even an additional inline doesn't buy you much.
C99 inline semantics are often misunderstood. The inline specifier serves two purposes:
First, as a compiler hint in case of static inline and extern inline declarations. Semantics remain unchanged if you remove the specifier.
Second, in case of raw inline (ie without static or extern) to provide an inline definition as an alternative to an external one, which has to be present in a different translation unit. Not providing the external one is undefined behaviour, which will normally manifest as linking failure.
This is particularly useful if you want to put a function into a shared library, but also make the function body available for optimization (eg inlining or specialization). Assuming a sufficiently smart compiler, this allows you to recover many of the benefits of C++ templates without having to jump through preprocessor hoops.
Note that it's a bit more messy than I described here as having another file scope non-inline external declaration will trigger the first case as described in Jens' answer, even if the definition itself is inline instead of extern inline. This is by design so you can have have a single inline definition in a header file, which you can include into the source file that provides the external one by adding a single line for the external declaration.
This is because of the way GCC handle inline function. GCC performs inline substitution as the part of optimization.
To remove this error use static before inline. Using static keyword force the compiler to inline this function, which makes the program compile successfully.
static inline int func(int i) {
return i+1;
}
...
i = func(i);

Define a function before main?

Are function declarations/prototypes necessary in C99 ?
I am currently defining my functions in a header file and #include-ING it in the main file. Is this OK in C99 ?
Why do most programmers declare/prototype the function before main() and define it after main() ? Isn't it just easier to define them before main and avoid all the declarations/prototypes ?
Contents of header.h file:
int foo(int foo)
{
// code
return 1;
}
Contents of main file:
#include <stdio.h>
#include "header.h"
int main(void)
{
foo(1);
return 0;
}
How and where to prototype and define a function in C :
Your function is used only in a specific .c file :
Define it static in the .c file. The function will only be visible and compiled for this file.
Your function is used in multiple .c files :
Choose an appropriate c file to host your definition (All foo related functions in a foo.c file for example), and have a related header file to have all non-static (think public) functions prototyped. The function will be compiled only once, but visible to any file that includes the header files. Everything will be put together at link time. Possible improvement : always make the related header file, the first one included in its c file, this way, you will be sure that any file can include it safely without the need of other includes to make it work, reference : Large Scale C++ projects (Most of the rules apply to C too).
Your function is inlinable (are you sure it is ?) :
Define the function static inline in an appropriate header file. The compiler should replace any call to your function by the definition if it is possible (think macro-like).
The notion of before-after another function (your main function) in c is only a matter of style. Either you do :
static int foo(int foo)
{
// code
return 1;
}
int main(void)
{
foo(1);
return 0;
}
Or
static int foo(int foo);
int main(void)
{
foo(1);
return 0;
}
static int foo(int foo)
{
// code
return 1;
}
will result in the same program. The second way is prefered by programmers because you don`t have to reorganize or declare new prototypes every time you declare a new function that use the other ones. Plus you get a nice list of every functions declared in your file. It makes life easier in the long run for you and your team.
People typically do it because it's easier to do with multiple files. If you declare in a header then you can just #include that header anywhere you need those functions. If you define them in a header and then include in another translation unit, bang.
Function declarations are required in C99. Function prototypes are not required in C99.
Declaring functions before the point of the call and defining them after the point of the call is a popular approach to structuring the program code. However, this is in no way what the "most" programmers do. On the contrary, a more popular approach is to define function before the point of the first call, in which case the separate declaration is not necessary. This approach requires less maintenance, which is why it is more popular than what you describe.
Separate declarations/definitions are normally used with external functions only, i.e. with functions used across several translation units. Such functions are declared in header files and defined in implementation files.
You should only ever define inline functions in headers. Although you can have extern inline functions, the common case is static inline.
Rule of thumb for header files:
function declarations should be extern
function definitions should be static inline
variable declarations should be extern
variable definitions should be static const
As C. Ross asked for it, here's reasoning behind it: A resource with external linkage should only ever be defined once[1]. It follows that definitions should not reside in header files, which are intended to be included in more than one place.
Having static definitions in header files won't lead to any problems, but is generally frowned upon because the code has to be compiled more than once and will be present in different object files, which will increase the executable size (assuming the linker isn't smart enough to figure out the code duplication).
The common exceptions to this rule are constants and inline functions, which are supposed to be visible to the compiler in each translation unit to make further optimizations possible.
Note: [1] This does not apply to inline functions with external linkage, but as it's unspecified which of the multiple definitions of an inline function will be used in the evaluation of a function designator, they are mostly useless
Your approach is fine for small programs. Header files are meant for declarations and constant definitions - they provide an interface to the program they "encapsulate". Headers are meant as an interface for other program units.
In case you have more .c files, forward declarations and header files are necessary, because a C function can be defined only once for the whole program (search for one definition rule), even though you may use the function anywhere (in any .c file). If you defined it in a header, it would get included in all .c files you use it in and result in multiple definitions.
It's quicker to do like that, but I personally prefer to have the main function at the beginning of the main file, and put the other functions in other files or below main.
Note that in your example you should avoid declaring foo() in a header file: you won't be able to include it in two different source files. Declare it in the C file containing main(); you won't need to define it elsewhere unless you're referring to it from some other files.
Yes, it is easier to define them before main. If you only want to use these functions from within the file, a prototype is not necessary. In that case however, you can also prepend the "static" keyword before the function definition. (In the C file.) That will ensure the function is not visible to other files. (At link time.)
Do not put static keywords in include files.
You should always prototype.
The reasons for this are;
methodical prototyping produces a succinct list in header files of the functions in the code - this is invaluable to future readers
in anything but the simplest projects, many functions will not have visibility prior to main.
main should be the first function in its file; it's easier for the reader, since we read down, not up
Why do most programmers declare/prototype the function before main() and define it after main() ?
Merely because most humans read sequentially. Start a story from the beginning, not the middle. Not necessary, just intuitive.
Of course if the code being prototyped is in a separate compilation unit, the prototypes are necessary.
It is always a good practice to declare the functions in either before main or in a separate header file which will be included in other c files where we have used that function. By doing this we can easily identify all the functions declared/defined in that .C or .H files. And we should use extern key word before declaring the function in header file.

Resources