flto改变符号可见性

GCC -flto changing symbol visibility

本文关键字:可见性 符号 改变 flto      更新时间:2023-10-16

我有一段很大的代码,仅在某些版本的gcc上使用-flto编译时会产生错误。我将试着总结如下

在file1.h

extern char A [100];
在file1.c

#include "file1.h"
char A[100];

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

的东西编译整个东西。
gcc file1.c cpp.o

在archlinux(5.2.0)上使用gcc版本,有和没有-flto都没有问题。然而,在Ubuntu 14.04(4.8.4)上使用gcc,当代码用-flto编译时,A变成了一个局部变量。我已经用nm验证了这一点:

这些是nm a.out对相关变量的输出

Ubuntu, no lto(很相似,只是编号不同):

00000000006162e0 B A

Ubuntu, lto

00000000006092c0 b A.2722

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

我如何确保A被维护为一个全局变量,即使我在Ubuntu上使用-flto ?

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

使用问题中的代码片段,
我可以在我运行Ubuntu 14.04的机器上重现这种行为。

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

file1.c char 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.