gcc - 2 个版本,内联函数的不同处理

问题描述 投票:0回答:1

最近我在项目中遇到了一个问题。我通常在 gcc-4 中编译它,但是在尝试在 gcc-3 中编译之后,我注意到内联函数的处理方式有所不同。为了说明这一点,我创建了一个简单的示例:

main.c:

#include "header.h"
#include <stdio.h>

int main()
{
    printf("f() %i\n", f());
    return 0;
}

文件.c:

#include "header.h"
int some_function()
{
    return f();
}

标题.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 被破坏了,我不应该在几个翻译单元中拥有内联函数的多个定义,除非它们是静态的?

c gcc inline c99
1个回答
5
投票

是的,从 gcc-4.3 开始,行为已经改变。 gcc 内联文档 (http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html) 详细介绍了这一点。

短篇故事:普通内联仅用于告诉 gcc(无论如何在旧版本中) 来自同一文件范围的内联调用。然而,它并没有告诉 gcc 所有调用者都来自文件范围,因此 gcc 还保留可链接版本 周围的

f()
:这解释了上面的重复符号错误。

Gcc 4.3 更改了此行为以与 c99 兼容。

并且,回答您的具体问题:

现在的问题是:我应该如何定义和声明简单的小函数,我想要内联它们,以便它们可以在整个项目中使用,而不用担心在各种编译器中出现问题?让它们全部静态是正确的做法吗?或者也许 gcc-4 被破坏了,我不应该在几个翻译单元中拥有内联函数的多个定义,除非它们是静态的?

如果您想要跨 gcc 版本的可移植性,请使用静态内联。

© www.soinside.com 2019 - 2024. All rights reserved.