The following code:
#include
inline int myfunc (int x) {
return x+3;
}
int main () {
printf(\"%d\", myfunc(2));
return 0;
}
In C99 you need to specify either a declaration to your inline function like
int myfunc(int);
or allow the compiler to actually inline the function by specifying -finline-functions
or -O3
.
Quoting the C99 standard:
Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.
So the compiler is free to use the external definition of myfunc
- which doesn't exist if you don't provide it, hence the linker error. Why does it prefer to choose a non existing external definition? Because you disallowed inlining by not using -finline-functions
or a optimization level which contains this flag.
This is the gnu_inline
hiccup. Use -std=gnu99 -fgnu89-inline
.
For more information see Function Attributes (item gnu_inline
).
The relevant passage:
In C, if the function is neither extern nor static, then the function is compiled as a standalone function, as well as being inlined where possible.
This is how GCC traditionally handled functions declared inline. Since ISO C99 specifies a different semantics for inline, this function attribute is provided as a transition measure and as a useful feature in its own right. This attribute is available in GCC 4.1.3 and later. It is available if either of the preprocessor macros GNUC_GNU_INLINE or GNUC_STDC_INLINE are defined. See An Inline Function is As Fast As a Macro.
You should declare 'myfunc' before define it. For example this code can be compiled with -std=gnu99 option:
#include <stdio.h>
int myfunc(int);
inline int myfunc (int x) {
return x+3;
}
int main () {
printf("%d", myfunc(2));
return 0;
}
UPDATED
Actually, regarding to the C standard inline keyword is just a suggestion to the C compiler. But compiler can choose not to inline. So it can do its own way, therefore.
In your example you can use function declaration as I showed above - or you can add optimization flag '-O3' (tested on linux gcc) and above - in this case your source code will compiled without extra-declaration.
UPDATED
Here you can find deeper explanation: https://blogs.oracle.com/dew/entry/c99_inline_function
Apparently you need to specify that you are using and you want to adopt inline functions
-fgnu89-inline
The option -fgnu89-inline tells GCC to use the traditional GNU semantics for "inline" functions when in C99 mode. This option is accepted and ignored by GCC versions 4.1.3 up to but not including 4.3. In GCC versions 4.3 and later it changes the behavior of GCC in C99 mode. Using this option is roughly equivalent to adding the "gnu_inline" function attribute to all inline functions.
The option -fno-gnu89-inline explicitly tells GCC to use the C99 semantics for "inline" when in C99 or gnu99 mode (i.e., it specifies the default behavior). This option was first supported in GCC 4.3. This option is not supported in C89 or gnu89 mode.
The preprocessor macros
__GNUC_GNU_INLINE__
and__GNUC_STDC_INLINE__
may be used to check which semantics are in effect for "inline" functions.Source: http://linux.die.net/man/1/gcc
So to compile your code you need at least this:
gcc source.c -std=gnu99 -fgnu89-inline