【问题标题】:Linker error inline function链接器错误内联函数
【发布时间】:2013-02-21 22:45:17
【问题描述】:

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

  • a.h:在这个文件中定义了一个声明为“inline”的函数,例如:inline void foo1();
  • b.h:在此文件中定义了一个声明为“内联”的函数,该函数调用 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 offoo1' prj/src/main.o:(.text+0x0): 首先在这里定义 make: * [内核] 错误 1

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

【问题讨论】:

  • 用static inline怎么样?
  • 我认为这行不通。静态属性意味着该函数仅在声明/定义的翻译单元中可见,并且我想在其他模块中使用该函数...
  • 不,等等。使用静态它可以工作...但是为什么呢? @75inchpianist
  • 当你#include一个文件时,它的所有内容都成为当前翻译单元的一部分。

标签: c gcc linker inline


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    我试过了,没有任何错误

    啊。

    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】:

      将inline 定义放在您的.h 文件中,并在.c 文件中强制外部定义。

      例如:

      // File: a.h
      inline void foo1(void) { /*...*/ }
      
      // File main.c
      #include "a.h"
      
      extern inline void foo1(void);
      
      int main(void)
      {
          /*...*/   
      }
      

      【讨论】:

      • 使用静态内联(在头文件中)它可以工作......但我不明白为什么。你能解释一下它为什么有效吗?
      • 此代码不使用static inline,仅使用inline。
      【解决方案4】:

      您可以考虑使用标头保护来防止重新定义。文件的实现如下。我尝试使用 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;
      }
      

      【讨论】:

        猜你喜欢
        • 2010-10-31
        • 2012-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-12
        • 2011-08-24
        • 1970-01-01
        相关资源
        最近更新 更多