我有一种奇怪的感觉gcc
处理事情时的行为弱常量变量在不同的优化级别(即-O0
or -O1
).
这是代码:
def.h:声明
const int var;
int copy;
int do_copy(void);
weak.c: weak var
定义,do_copy
实施做copy = var
#include "def.h"
const int __attribute__((weak)) var = 1;
int do_copy(void)
{
copy = var;
return var;
}
main.c: 强的var
的定义和使用do_copy
#include <stdio.h>
#include "def.h"
int copy = 0;
int copy2 = 0;
const int var = 2;
int main(void)
{
copy2 = do_copy();
printf("copy=%d, copy2=%d\n", copy, copy2);
return 0;
}
从这个“main.c”代码中,我期待两者copy
and copy2
留住强者var
价值,存在2
.
这是带有一个的输出-O0
优化:
$ gcc -O0 -c main.c -o main0.o
$ gcc -O0 -c weak.c -o weak0.o
$ gcc main0.o weak0.o -o main0
$ ./main0
copy=2, copy2=2
这是预期的结果。
这是带有一个的输出-O1
优化:
$ gcc -O1 -c main.c -o main1.o
$ gcc -O1 -c weak.c -o weak1.o
$ gcc main1.o weak1.o -o main1
$ ./main1
copy=1, copy2=2
This is 意外: while copy2
确实保留了强大的价值(2
), copy
实际上设置为弱值(1
)!
在“weak.c”文件中,它看起来像var
总是被评估为1
.
我的看法是var
被宣布const
,编译器认为它的值永远是1
并对整个文件进行此优化(除了return
陈述)。因此,它错过了弱/强的事情,并且不关心“main.c”中的强重新定义!
该问题可以通过以下方式解决:
- 设置弱定义(
const int __attribute__((weak)) var = 1;
)在一个单独的文件中,说“weak2.c”。
- 不做
var
持续的 (这可能是不可接受的!): const int var;
--->int var;
.
尽管如此,这看起来还是一个gcc
对我来说很麻烦,但我错过了什么吗?
附录:
这是使用的版本gcc
:
$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0