Linker error inline function
Asked Answered
B

4

8

I got some compiler/linker errors and i don't know what is the correct method to proceed. I'm in this situation:

  • a.h: in this file is defined a function declared as "inline", for example: inline void foo1();
  • b.h: in this file is defined a function declared as "inline" that calls foo1(): inline void foo2();
  • main.c: there are some functions calls of both foo1 and foo2().

Now, if i declare foo1 and foo2 in a.h and b.h as extern inline void i got the following error:

prj/src/b.o: In function foo1': (.text+0x0): multiple definition offoo1' prj/src/main.o:(.text+0x0): first defined here make: * [kernel] Error 1

What is the way which allow to compile and link without errors/warning in the situation i described?

Bedwarmer answered 21/2, 2013 at 22:45 Comment(5)
What about using static inline?Shimmy
I think it will not work. The static attribute means that function it's only visible in the translation unit where is declared/defined and i want to use that functions in other modules...Bedwarmer
No, wait. With static it works... but why? @75inchpianistBedwarmer
When you #include a file, all of its contents become part of the current translation unit.Interrogate
possible duplicate of Multiply defined linker error using inlined functions (or Multiple definition of inline function, or ...)Managing
S
21

From http://gcc.gnu.org/onlinedocs/gcc/Inline.html:

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.

In other words, without static, it emits a symbol for your inline function. If you happen to define that function in a header and include it in more than one compilation unit, then you end up with multiple (redefined) symbols. If you want to include the definition in the header, you should make it static.

Shimmy answered 21/2, 2013 at 23:11 Comment(0)
N
0

Put the inline definitions in your .h file and in the .c files force an external definition.

For example:

// File: a.h
inline void foo1(void) { /*...*/ }

// File main.c
#include "a.h"

extern inline void foo1(void);

int main(void)
{
    /*...*/   
}
Nazi answered 21/2, 2013 at 22:54 Comment(2)
With static inline(in header files) it works... but i've not understood why. Can you explain me why it works?Bedwarmer
This code does not make use of static inline only inline.Nazi
O
0

I tried it and didn't get any errors

a.h

extern inline void foo1()
{
    return;
}

b.h

extern inline void foo2()
{
    foo1();
    return;
}

main.cpp

#include "a.h"
#include "b.h"

int main() {
    foo1();
    foo2();
    return 0;
}
Outrigger answered 21/2, 2013 at 22:56 Comment(0)
S
0

You may consider using header guards to prevent redefinition. The implementation of the files is as follows. I tried compilation for the following files using CMake and it worked without any problem.

a.h

#ifndef A_H
#define A_H

inline
void foo1()
{
    return;
}

#endif

b.h

#ifndef B_H
#define B_H

#include "a.h"

inline
void foo2()
{
    foo1();
    return;
}

#endif

main.cpp

#include "a.h"
#include "b.h"

int main() {
    foo1();
    foo2();
    return 0;
}
Schoolgirl answered 6/2, 2020 at 4:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.