链接器错误内联函数

时间:2013-02-21 22:45:18

标签: c gcc linker inline

我遇到了一些编译器/链接器错误,我不知道正确的方法是什么。我处于这种情况:

  • a.h:在此文件中定义了一个声明为“inline”的函数,例如:inline void foo1();
  • b.h:在这个文件中定义了一个声明为“inline”的函数,它调用foo1():inline void foo2();
  • main.c:foo1和foo2()都有一些函数调用。

现在,如果我在a.h和b.h中声明foo1和foo2作为extern inline void,我得到以下错误:

  

prj / src / b.o:在函数foo1': (.text+0x0): multiple definition of foo1'中   prj / src / main.o :(。text + 0x0):首先在这里定义make: *   [内核]错误1

在我描述的情况下,允许编译和链接而没有错误/警告的方式是什么?

4 个答案:

答案 0 :(得分:15)

来自http://gcc.gnu.org/onlinedocs/gcc/Inline.html

  

当内联函数不是静态的时,编译器必须假设   可能有来自其他源文件的调用;自全球化的象征   在任何程序中只能定义一次,函数不能是   在其他源文件中定义,因此其中的调用不能   集成。因此,始终编译非静态内联函数   以通常的方式独立。

换句话说,如果没有static,它会为您的内联函数发出一个符号。如果您碰巧在标头中定义该函数并将其包含在多个编译单元中,那么您最终会得到多个(重新定义的)符号。如果要在标题中包含定义,则应将其设为static

答案 1 :(得分:0)

inline定义放在.h文件和.c文件中强制外部定义。

例如:

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

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

extern inline void foo1(void);

int main(void)
{
    /*...*/   
}

答案 2 :(得分:0)

我试过了,没有出现任何错误

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;
}

答案 3 :(得分:0)

您可以考虑使用标头保护符来防止重新定义。文件的实现如下。我尝试使用CMake编译以下文件,并且没有任何问题。

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;
}