Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiple definition of inline function

Tags:

I have gone through some posts related to this topic but was not able to sort out my doubt completely. This might be a very naive question.

I have a header file inline.h and two translation units main.cpp and tran.cpp.

Details of code are as below

inline.h

#ifndef __HEADER__ #include <stdio.h> extern inline int func1(void) { return 5; }  static inline int func2(void) { return 6; }  inline int func3(void) { return 7; } #endif 

main.c

#define <stdio.h> #include <inline.h> int main(int argc, char *argv[]) {     printf("%d\n",func1());     printf("%d\n",func2());     printf("%d\n",func3());     return 0; } 

tran.cpp

//(note that the functions are not inline here) #include <stdio.h> int func1(void) { return 500; }  int func2(void) { return 600; }  int func3(void) { return 700; } 

The above code compiles in g++, but does not compile in gcc (even if you make changes related to gcc like changing the code to .c, not using any C++ header files, etc.). The error displayed is "duplicate definition of inline function - func3".

Can you clarify why this difference is present across compilers?

Also, when you run the program (g++ compiled) by creating two separate compilation units (main.o and tran.o) and create an executable a.out, the output obtained is:

500
6
700

Why does the compiler pick up the definition of the function which is not inline. Actually, since #include is used to "add" the inline definition I had expected 5,6,7 as the output. My understanding was during compilation since the inline definition is found, the function call would be "replaced" by inline function definition.

Can you please tell me in detailed steps the process of compilation and linking which would lead us to 500,6,700 output. I can only understand the output 6.

like image 483
K71993 Avatar asked Apr 27 '10 14:04

K71993


People also ask

How do you define an inline function?

An inline function is one for which the compiler copies the code from the function definition directly into the code of the calling function rather than creating a separate set of instructions in memory. This eliminates call-linkage overhead and can expose significant optimization opportunities.

What is inline function definition in C++?

Inline function in C++ is an enhancement feature that improves the execution time and speed of the program. The main advantage of inline functions is that you can use them with C++ classes as well.

What is inline function given example?

Example 1. C++ Copy. // inline_keyword1.cpp // compile with: /c inline int max( int a , int b ) { if( a > b ) return a; return b; } A class's member functions can be declared inline, either by using the inline keyword or by placing the function definition within the class definition.

What is inline function and its limitations?

Limitations of Inline FunctionsInline functions do not work if the body of the function contains any sort of looping or iteration. Inline functions do not support the use of switch or goto statements. C++ Inline functions cannot work if the function defined is recursive in nature.


2 Answers

This answer is divided into the following sections:

  1. How to reproduce the duplicate definition of inline function - func3 problem and why.
  2. Why defintion of func3 is a duplicate instead of func1.
  3. Why it compiles using g++

How to produce the duplicate definition of inline function - func3 problem

The problem can be successfully reproduced by

  1. Rename tran.cpp to tran.c
  2. Compile with gcc -o main main.c tran.c

@K71993 is actually compiling using the old gnu89 inline semantics, which is different from C99. The reason for renaming tran.cpp to tran.c is to tell the gcc driver to treat it as C source instead of C++ source.


Why definition of func3 is a duplicate instead of func1.

GNU 89 inline semantics

The following text is quoted from GCC Document: An Inline Function is As Fast As a Macro explains why func3 is a duplicate definition instead of func1, since func3 (instead of func1) is an externally visible symbol (in GNU89 inline semantics)

When an inline function is not static, then the compiler must assume that there may be calls from other source files; since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. Therefore, a non-static inline function is always compiled on its own in the usual fashion.

If you specify both inline and extern in the function definition, then the definition is used only for inlining. In no case is the function compiled on its own, not even if you refer to its address explicitly. Such an address becomes an external reference, as if you had only declared the function, and had not defined it.

C99 inline semantics

If compiled with C99 standard, i.e., gcc -o main main.c tran.c -std=c99, the linker will complain that definition of func1 is a duplicate due to the reason that extern inline in C99 is a external definition as mentioned in other posts and comments.

Please also refer to this execellent answer about semantic differents between GNU89 inline and C99 inline.

Why it compiles using g++.

When compiled with g++, the source program are considered as C++ source. Since func1, func2 and func3 are defined in multiple translation units and their definitions are different, the One Defintion Rule of C++ is violated. Since the compiler is not required to generate dignostic message when definitions spans multiple translation units, the behavior is undefined.

like image 146
Lei Mou Avatar answered Sep 18 '22 13:09

Lei Mou


The compiling error is because there is a duplicate definition of func1();

Because func1() is defined using extern inline, it will produce a external definition.

However, there is also an external definition in tran.c, which cause multiple definition error.

However, func2() and func3() do not produce an external definition, hence no redefinition error.

You might want to look at here http://www.greenend.org.uk/rjk/2003/03/inline.html.

Also, take a note that c++ and c treats inline functions differently, and even in c, different standards (c89 vs. c99) treats inline functions differently.

like image 29
SHH Avatar answered Sep 19 '22 13:09

SHH