8

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

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

现在,如果我将 ah 和 bh 中的 foo1 和 foo2 声明为 extern inline void,我会收到以下错误:

prj/src/bo: 在函数foo1': (.text+0x0): multiple definition offoo1' prj/src/main.o:(.text+0x0): 首先在这里定义 make: * [kernel] Error 1

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

4

4 回答 4

21

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

当内联函数不是静态的时,编译器必须假设可能有来自其他源文件的调用;由于一个全局符号在任何程序中只能定义一次,因此不能在其他源文件中定义该函数,因此不能集成其中的调用。因此,非静态内联函数总是以通常的方式自行编译。

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

于 2013-02-21T23:11:51.613 回答
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)
{
    /*...*/   
}
于 2013-02-21T22:54:15.890 回答
0

我试过了,没有收到任何错误

extern inline void foo1()
{
    return;
}

bh

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

主文件

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

int main() {
    foo1();
    foo2();
    return 0;
}
于 2013-02-21T22:56:58.187 回答
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;
}
于 2020-02-06T04:19:51.090 回答