GCC -flto改变符号可见性

Joh*_*mer 5 c c++ optimization gcc compilation

我有一大段代码,-flto只在某些版本的gcc上编译时会产生错误.我将在下面总结一下

在file1.h

extern char A [100];
Run Code Online (Sandbox Code Playgroud)

在file1.c中

#include "file1.h"
char A[100];
Run Code Online (Sandbox Code Playgroud)

我也有一些使用变量的c ++代码A.C++代码被编译成一个.o文件,然后整个事情被编译成类似的东西

gcc file1.c cpp.o
Run Code Online (Sandbox Code Playgroud)

在archlinux(5.2.0)上使用gcc版本,无论是否有问题都没有-flto.但是在Ubuntu 14.04(4.8.4)上使用gcc时,编译代码时-flto,A会成为局部变量.我用nm证实了这一点:

这些是有nm a.out问题变量的输出

Ubuntu,没有lto(拱门类似,有不同的编号):

00000000006162e0 B A
Run Code Online (Sandbox Code Playgroud)

Ubuntu,lto

00000000006092c0 b A.2722
Run Code Online (Sandbox Code Playgroud)

我的理解是,它B是一个全局变量,而b不是.

A即使我-flto在Ubuntu上使用,如何确保将其保持为全局变量?

The*_*ist 2

看看这个这个,它肯定是您正在使用的特定版本的 gcc 中的一个错误(gcc 4.8.4 与 Ubuntu 14.04 捆绑在一起)。

使用问题中的代码片段,
我能够在运行 Ubuntu 14.04 的计算机上重现该行为。

一个简单的解决方法是将有问题的符号显式标记为used

file1.cchar A[100];

file2.c__attribute__((used)) char A[100];

gcc file1.c -o file1-default.o
nm file1-default.o | grep "A$"
0000000000601060 B A               <-- symbol is a global.

gcc file1.c -flto -o file1-flto.o
nm file1-flto.o | grep "A$"
0000000000601060 b A.2385          <-- symbol updated to a local.

gcc file2.c -flto -o file2.o
nm file2.o | grep "A$"
0000000000601060 B A               <-- symbol retained as global.
Run Code Online (Sandbox Code Playgroud)