问题
I'm getting a weird gcc
behaviour when dealing with weak const variables on different optimize levels (i.e. -O0
or -O1
).
Here is the code:
def.h: declarations
const int var;
int copy;
int do_copy(void);
weak.c: weak var
definition, do_copy
implementation doing copy = var
#include "def.h"
const int __attribute__((weak)) var = 1;
int do_copy(void)
{
copy = var;
return var;
}
main.c: strong var
definition, and use of 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;
}
From this 'main.c' code, I am expecting both copy
and copy2
to retain the strong var
value, being 2
.
Here is the output with a -O0
optimization:
$ 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
This is the expected result.
Here is the output with a -O1
optimization:
$ 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 unexpected: while copy2
does retain the strong value (2
), copy
is actually set to the weak value (1
)!
Within the 'weak.c' file, it looks like var
is always evaluated to 1
.
My take is that as var
is declared const
, the compiler thinks that its value will always be 1
and does this optimization on the whole file (except for the return
statement). Hence, it misses the weak/strong thing, and does not care about the strong redefinition in 'main.c'!
The issue can be solved by :
- setting the weak definition (
const int __attribute__((weak)) var = 1;
) in a separate file, say 'weak2.c'. - not making
var
constant (which might not be acceptable!):const int var;
--->int var;
.
Still, this looks like a gcc
bug to me, but am I missing something?
Appendix:
This is the used version of gcc
:
$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
来源:https://stackoverflow.com/questions/65411966/gcc-optimization-bug-on-weak-const-variable