【问题标题】:what could cause multiple definition error again after I declare the function inline?什么会在我声明函数内联后再次导致多重定义错误?
【发布时间】:2011-12-14 09:06:32
【问题描述】:

我有这个包含很多内联函数的头文件,编译后它说: 函数的多重定义***,函数如下:

inline int testab(int a, int b)
{
        return a>b;
}

在内联前面添加静态后,错误消失了。这是正确的方法吗?还是我错过了什么?我想我可以在这样的标题中设置内联函数。

【问题讨论】:

  • 你应该至少指定你在这里谈论的编译器和语言。
  • 我读了另一个线程,他们更喜欢在标题中定义内联函数,并在c中编写函数,所以我该怎么办,我只是使用了大量这些函数。
  • 我正在使用 gcc 4.5 和 c 程序
  • 好的 - 请适当地标记您的问题
  • 要了解为什么会出现此错误,请参阅此答案:stackoverflow.com/questions/2217628/…

标签: c gcc header inline


【解决方案1】:

inline 与否,一旦标头被复制到至少两个文件中,您将无法再链接这些文件。

您可以安全地在标头中实现函数的唯一方法是使用static。这样,该函数的每个副本对其他副本都是不可见的。

注意,没有限制一起使用它们,所以你可以放心地写:

static inline bool testab(int a, int b)
{
        return a>b;
}

编辑:更多细节

inline 告诉编译器认为函数足够小可以内联。也就是说,您告诉编译器您认为内联函数的额外空间与(轻微的)(可能的)性能增益相比并不重要。然而,大多数编译器都足够聪明,可以自行决定并使用您的关键字,他们只会倾向于更多地内联,而不一定总是听你的。当然,这取决于编译器。一些编译器可能会完全忽略该关键字。

static 另一方面,意味着无论定义了静态变量的范围是什么,它在它之外都是不可见的。如果你在函数中有一个static 变量,那么它在它之外是不可见的。如果文件中有static 变量(即静态全局变量),它在外部是不可见的,这意味着编译后该符号不存在,供链接器查看和混淆。这就是为什么,如果您编写的库中存在不应该在库外可见的全局变量或函数,您应该将它们声明为static

编辑 2:更正

显然,根据this 的回答,inline 函数不应为链接器导出其标识符。尽管如此,您可以将static 附加到它上面,以使其更清晰。同样显然,一些编译器无论如何都会导出标识符,所以在这些情况下static 确实是必要的。

【讨论】:

  • @JohannesSchaub-litb 想解释一下什么是正确的?或者更好,哪里错了?
  • 查看我对问题的评论
  • @JohannesSchaub-litb,怎么会这样?可能不是很清楚,但我看不到任何错误。
【解决方案2】:

如果您在头文件中定义函数,则需要指定static,否则会为该函数创建多个符号表定义(每个.c 文件中的一个),并且在您尝试链接各自的目标文件时会发生冲突. 要在标题中定义内联函数,我相信您需要:

static inline int foo(int x) __attribute__((always_inline))
    {
    return x+1;
    }

不确定这是否完全正确;见:http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Inline.html#Inline

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2020-03-20
    • 2011-10-31
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 2016-05-13
    • 2017-07-27
    • 1970-01-01
    相关资源
    最近更新 更多