最近我在我的项目中遇到了一个问题。我通常用gcc-4编译它,但在尝试用gcc-3编译后,我注意到对内联函数的不同处理。为了说明这一点,我创建了一个简单的示例:
main.c:
#include "header.h"
#include <stdio.h>
int main()
{
printf("f() %i\n", f());
return 0;
}file.c:
#include "header.h"
int some_function()
{
return f();
}header.h
inline int f()
{
return 2;
}当我使用以下命令编译gcc-3.4.6中的代码时:
gcc main.c file.c -std=c99 -O2我得到了链接器错误(f的多个定义),如果我删除了-O2标志,也是如此。我知道编译器不需要内联任何东西,所以我假设它将f放在目标文件中,而不是在main.c和file.c的情况下内联它,从而导致多定义错误。显然,我可以通过将f设为静态来解决这个问题,然后,在最坏的情况下,在二进制文件中使用一些f。
但我尝试使用以下命令在gcc-4.3.5中编译此代码:
gcc main.c file.c -std=c99 -O2一切都运行得很好,所以我假设在两种情况下都是较新的gcc内联的f,并且在二进制文件中根本没有f函数(在gdb中检查,我是对的)。
然而,当我删除-O2标志时,我得到了两个未定义的对int f()的引用。在这里,我真的不明白发生了什么。看起来像是gcc假设f是内联的,所以它没有把它添加到目标文件中,但是后来(因为没有-O2)它决定生成对这些函数的调用而不是内联,这就是链接器错误的来源。
现在问题来了:我应该如何定义和声明简单和小的函数,我希望这些函数是内联的,这样它们就可以在整个项目中使用,而不用担心各种编译器中的问题?让它们都是静态的是正确的做法吗?或者可能是gcc-4被破坏了,我永远不应该在几个翻译单元中有内联函数的多个定义,除非它们是静态的?
发布于 2010-06-23 17:44:29
是的,从gcc-4.3开始,行为发生了变化。gcc的内联文档(http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html)详细说明了这一点。
小故事:纯内联只用于告诉gcc (至少在旧版本中)从相同的文件作用域内联调用。然而,它并没有告诉gcc所有的调用者都来自文件作用域,因此gcc还保留了一个可链接版本的f():这解释了上面的重复符号错误。
为了与c99兼容,Gcc 4.3更改了这一行为。
然后,回答你的具体问题:
现在的问题来了:我应该如何定义和声明简单和小的函数,我希望这些函数是内联的,这样它们就可以在整个项目中使用,而不用担心各种编译器中的问题?让它们都是静态的是正确的做法吗?或者可能是gcc-4被破坏了,我永远不应该在几个翻译单元中有内联函数的多个定义,除非它们是静态的?
如果你想要跨gcc版本的可移植性,请使用静态内联。
https://stackoverflow.com/questions/3100429
复制相似问题