Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling error when -std=gnu99 and inline function is used

Tags:

c

gcc

The following code:

#include <stdio.h>
inline int myfunc (int x) {
    return x+3;
}

int main () {

    printf("%d", myfunc(2));
    return 0;
}

does not compile when I use the -std=gnu99 flag (I am compiling with gcc). This is the error it throws:

gcc -std=gnu99 -c main.c -o main.o
gcc -std=gnu99 main.o -o main
main.o: In function `main':
main.c:(.text+0x15): undefined reference to `myfunc'
collect2: ld returned 1 exit status
make: *** [main] Error 1

The compilation goes with no problems when -std=gnu99 is omitted. Does anyone know why is the linker complaining if -std=gnu99 is used?

like image 504
pap42 Avatar asked Oct 05 '12 13:10

pap42


People also ask

Can compiler ignore inline function?

Remember, inlining is only a request to the compiler, not a command. Compiler can ignore the request for inlining. Compiler may not perform inlining in such circumstances like: If a function contains a loop.

Which situation is not suitable for inline functions?

All those functions that contain a loop statement (for loop, while loop, or do-while loop) can not be considered as an inline function by the compiler. The compiler will not consider a function to be an inline function if it is recursive.

When might a compiler choose not to inline a function declared as inline?

The compiler can't inline a function if: The function or its caller is compiled with /Ob0 (the default option for debug builds). The function and the caller use different types of exception handling (C++ exception handling in one, structured exception handling in the other). The function has a variable argument list.

Is inline function called during compile time?

Whether something is inline or not is part of code generation. That's the compiler's job. Ergo, inlining is done at compile time.


1 Answers

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.

like image 108
Gunther Piez Avatar answered Oct 12 '22 21:10

Gunther Piez