Mic*_*bus 3 c compiler-construction gcc inline c99
最近我在我的项目中遇到了一个问题.我通常在gcc-4中编译它,但在尝试在gcc-3中编译之后,我注意到了对内联函数的不同处理.为了说明这一点,我创建了一个简单的例子:
main.c中:
#include "header.h"
#include <stdio.h>
int main()
{
printf("f() %i\n", f());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
file.c:
#include "header.h"
int some_function()
{
return f();
}
Run Code Online (Sandbox Code Playgroud)
header.h
inline int f()
{
return 2;
}
Run Code Online (Sandbox Code Playgroud)
当我用gcc-3.4.6编译代码时:
gcc main.c file.c -std=c99 -O2
Run Code Online (Sandbox Code Playgroud)
我得到链接器错误(f的多个定义),如果我删除-O2标志,则相同.我知道,编译器没有内联任何东西,如果它不想要的,所以我认为它放在F中的目标文件中,而不是在这两个的情况下,内联它main.c和file.c,因此多个定义错误.显然,我可以通过制作f静态来解决这个问题,然后,在最坏的情况下,f在二进制文件中有一些.
但我尝试在gcc-4.3.5中使用以下代码编译此代码:
gcc main.c file.c -std=c99 -O2
Run Code Online (Sandbox Code Playgroud)
一切都运行正常,所以我假设f在两种情况下内联的新gcc 并没有f在二进制文件中有任何功能(在gdb中检查我是对的).
但是,当我删除-O2标志时,我得到两个未定义的引用int f().在这里,我真的不明白发生了什么.似乎gcc假设f会内联,所以它没有将它添加到目标文件中,但后来(因为没有-O2)它决定生成对这些函数的调用而不是内联,这就是链接器错误来自的地方.
现在问题是:我应该如何定义和声明我想要内联的简单和小函数,以便它们可以在整个项目中使用而不必担心各种编译器中的问题?并且让所有这些都成为静态的正确的事情吗?或者也许gcc-4被打破了,除非它们是静态的,否则我不应该在几个翻译单元中有多个内联函数的定义?
是的,行为已经从gcc-4.3开始改变了.gcc内联文档(http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html)详细说明了这一点.
简短的说明:简单内联只能告诉gcc(无论如何在旧版本中)内联调用来自同一文件范围.但是,它并没有告诉gcc所有调用者都来自文件范围,因此gcc还保留了f()around 的可链接版本 :这解释了上面的重复符号错误.
Gcc 4.3改变了这种行为以与c99兼容.
并且,回答您的具体问题:
现在问题是:我应该如何定义和声明我想要内联的简单和小函数,以便它们可以在整个项目中使用而不必担心各种编译器中的问题?并且让所有这些都成为静态的正确的事情吗?或者也许gcc-4被打破了,除非它们是静态的,否则我不应该在几个翻译单元中有多个内联函数的定义?
如果您希望跨gcc版本的可移植性使用静态内联.
| 归档时间: |
|
| 查看次数: |
892 次 |
| 最近记录: |