I am trying to learn the difference between static and extern functions in detail.
I know the basic difference between static and extern inline functions.
Please correct my understanding if it is wrong:
Below is a sample code where I got stuck about the behaviour.
file1.c
#include <stdio.h>
#include "file.h"
int main(void)
{
fun1();
return 0;
}
static inline void fun1(void)
{
int i;
for (i = 0; i < 10; i++) {
static int k = 20;
printf("Value : %d \n", k++);
}
}
file2.c
#include <stdio.h>
inline void fun1(void)
{
int i;
int k = 0;
for (i = 0; i < 10; i++) {
printf("Value : %d \n", k++);
}
}
file.h
#ifndef FILE_H
#define FILE_H
extern inline void fun1(void);
#endif
When I compile the above code "gcc file1.c file2.c", fun1 was called from file2.c. This is clear as it fun1 is declared as extern, it should take the extern function in file2.c( all inline functions are extern by default?).
But when I change the static inline function to static function(static void fun1(void)) in file1.c, fun1 was called from file1.c. What could be the reason ?
I also read like "If an inline function is declared with external linkage but not defined in the same translation unit, the behavior is undefined ". But I didnt understand this. Is this possible to explain with above example?
Is there any difference between static and extern functions in C++ when compared to C ?
Your code is incorrect because you cannot declare a function with extern
(which is default) and afterwards provide a static
definition. The fact that it compiles at all does not indicate anything useful.
From n1548 §6.2.2:
If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.
So, you get something like this in file1.c
:
// Has external linkage (which is the default!)
extern inline void fun1(void);
// This would also have external linkage.
inline void fun1(void);
// This has static linkage.
static inline void fun1(void) {
...
}
(Note: "external linkage" is the default but extern inline
actually means something special, it's different from inline
.)
Bam! Undefined behavior. The compiler may not even give you an error message, although some compilers appear to give error messages for this.
error: static declaration of 'func' follows non-static declaration
This error actually has nothing to do with the fact that the function is inline
. It is an error with or without inline
.
static inline functions are visible only to translation unit where it is defined.
This is true of all static
functions. They have "internal linkage" so you can have static void func(void);
in one file and a completely different static int func(char *p);
in a different file. The inline
makes no difference here.
extern inline functions can be access in more than one translation units.
Yes, which is why you shouldn't put them in header files. If you put them in header files, you will get multiple different definitions of the same function, which can all be accessed from different translation units. This is an error. Instead, put the extern inline
in source files, but it only needs to be a declaration, not a definition.
Better to define inline functions in header files
There is no real point to defining an inline function anywhere else. If your function is only used in one file just mark it static
and the compiler will decide how to call the function.
There is no difference between static and static inline function definitions.
Yes, there is no difference.
Well, technically, no, there is a difference because the compiler is allowed to treat static inline
functions differently from just static
functions. However, modern compilers tend to decide to inline functions using their own set of rules, and whether a function is inline
doesn't affect that process very much.
Well, practically there is one other difference. A static inline
function definition won't generate a warning in GCC if it's not used, but a static
function will. This is so you can put a static inline
function in a header file. This is an alternative to putting inline
in the header file, which requires you to have an extern inline
for that function somewhere in your program. However, if the compiler decides that it would rather not inline your static inline
function, either because it think's that inlining is worse or because inlining is impossible, then it will have to make a separate copy of that function in each file it's used in.
Never declare a function static
if it has a previous, non-static declaration. This is an error, even if it compiles.
Don't declare an inline extern
function in a header file. This creates an "external definition" for the function, and you can only have one of those in your entire program.
Don't declare inline
functions in header files without defining them. There is no point.
Here is how you would want to do this:
In mylib.h
:
// Provide "inline definition" of the function.
inline int times_two(int x) {
return x * 2;
}
In mylib.c
:
#include "mylib.h"
// Provide "external definition" of the function.
extern inline int times_two(int x);
This is the standard way to do things since C99. The compiler should be free to use the internal definition or the external definition, whichever one it thinks is better. If you don't have an external definition or you have more than one, you may get a linking error, just like with regular functions.
C++ has its own completely different rules for inline functions.
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