Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inline function in header file in C [duplicate]

Tags:

c

inline

I tried to search a good answer online but fail to get one I can fully understand. Suppose I have a header "add.h":

inline int add(int a, int b){ return a+b; }

A file called "adddouble.c":

#include "add.h"

int adddouble(int a, int b){ return 2*add(a,b); }

A file called "addsquare.c":

#include "add.h"

int addsquare(int a, int b){ return add(a,b)*add(a,b); }

A main file "main.c":

#include<stdio.h>

int adddouble(int, int);
int addsquare(int, int);
int main(){
printf("add double = %d\n", adddouble(10,20));
printf("add square = %d\n", addsquare(10,20));
return 0;
}

I use gcc5.2.0 to compile those files, but got: "Undefined symbols for architecture x86_64:". If I add static to inline function in add.h or add declaration "extern int add(int, int);" to "adddouble.c", it compiles successfully without errors. I am new to inline function, I don't know how to explain and understand this behaviour. thanks

like image 231
Lucas Hu Avatar asked Dec 07 '15 17:12

Lucas Hu


1 Answers

According to http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf, it looks like inline functions behave differently in C and C++:

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. 140)

If you don't put static there, you're defining an inline function with external linkage without instantiating an external definition.

extern int add(int, int); instatiates the external definition for that function, and you need to do that exactly once (doesn't matter in which file) for the linking to succeed (or you can mark the inline function static and the problem vanishes).

(In C++ the inline creates weak external definitions in each translation unit so you don't have to worry about marking things static or instantiating exactly one external definition for the inline function--g++ should straightforwardly compile it with for f in *.c; do g++ -c "$f"; done; g++ *.o without any problems.)

like image 171
PSkocik Avatar answered Oct 04 '22 10:10

PSkocik