GCC -O2 和 __attribute__((弱))

use*_*859 5 c gcc weak-linking

它看起来像 GCC,-O2__attribute__((weak))根据您引用弱符号的方式产生不同的结果。考虑一下:

$ catweak.c

#include <stdio.h>

extern const int weaksym1;
const int weaksym1 __attribute__(( weak )) = 0;

extern const int weaksym2;
const int weaksym2 __attribute__(( weak )) = 0;

extern int weaksym3;
int weaksym3 __attribute__(( weak )) = 0;

void testweak(void)
{
    if ( weaksym1 == 0 )
    {
        printf( "0\n" );
    }
    else
    {
        printf( "1\n" );
    }

    printf( "%d\n", weaksym2 );


    if ( weaksym3 == 0 )
    {
        printf( "0\n" );
    }
    else
    {
        printf( "1\n" );
    }
}
Run Code Online (Sandbox Code Playgroud)

$ cat test.c

extern const int weaksym1;
const int weaksym1 = 1;

extern const int weaksym2;
const int weaksym2 = 1;

extern int weaksym3;
int weaksym3 = 1;

extern void testweak(void);

void main(void)
{
    testweak();
}
Run Code Online (Sandbox Code Playgroud)

$ make

gcc  -c weak.c
gcc  -c test.c
gcc  -o test test.o weak.o
Run Code Online (Sandbox Code Playgroud)

$ ./测试

1
1
1
Run Code Online (Sandbox Code Playgroud)

$ make ADD_FLAGS="-O2"

gcc -O2 -c weak.c
gcc -O2 -c test.c
gcc -O2 -o test test.o weak.o
Run Code Online (Sandbox Code Playgroud)

$ ./测试

0
1
1
Run Code Online (Sandbox Code Playgroud)

问题是,为什么最后一个“./test”产生“0 1 1”,而不是“1 1 1”?

gcc 版本 5.4.0 (GCC)

nnn*_*nnn 3

看起来在进行优化时,编译器在声明符号constweak在同一编译单元中定义符号时遇到了问题。

您可以创建一个单独的 c 文件并将 const 弱定义移动到那里,它将解决该问题:

弱定义.c

const int weaksym1 __attribute__(( weak )) = 0;
const int weaksym2 __attribute__(( weak )) = 0;
Run Code Online (Sandbox Code Playgroud)

这个问题描述了同样的问题:GCC Weak attribute on Constant Variables