2015-07-29 12 views
5

Ho una grande parte di codice, che produce errori quando compilata usando -flto solo su alcune versioni di gcc. Cercherò di riassumere qui di seguitoGCC - cambio della visibilità dei simboli

in file1.h

extern char A [100]; 

in file1.c

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

ho anche un po 'di codice C++ che utilizza la variabile A. Il codice C++ viene compilato in un file .o, e quindi il tutto è stato compilato con qualcosa come

gcc file1.c cpp.o 

Utilizzando la versione di gcc su Archlinux (5.2.0), non c'è nessun problema con e senza -flto. Comunque usando gcc su Ubuntu 14.04 (4.8.4), quando il codice è compilato con -flto, A diventa una variabile locale. Ho verificato questo con nm:

Questi sono l'output nm a.out per la variabile in questione

Ubuntu, non lto (arco simile, con un numero diverso):

00000000006162e0 B A 

Ubuntu, lto

00000000006092c0 b A.2722 

mia comprensione è che il B è per una variabile globale, e b non è.

Come è possibile garantire che A venga gestito come variabile globale anche quando si utilizza -flto su Ubuntu?

+0

aggiorna il compilatore un'opzione? Che ne dici di un file oggetto separato a.o che contiene il buffer "char a [100];", con tutti gli altri che lo utilizzano "extern"? – technosaurus

+0

Il programma funziona come desiderato su Ubuntu? L'hai provato o stai solo ispezionando le tabelle dei simboli? – idmean

+0

@idmean Il programma fallisce sicuramente su Ubuntu quando viene eseguito con un errore di ricerca di simboli –

risposta

2

Guardando a this e this, è sicuramente un bug nella particolare versione di gcc che si sta utilizzando (gcc 4.8.4 viene fornito in bundle con Ubuntu 14.04).

Utilizzo dei frammenti di codice dalla domanda,
sono stato in grado di riprodurre il comportamento sul mio computer con Ubuntu 14.04.

Una semplice soluzione per questo è di contrassegnare in modo esplicito il simbolo in questione come used.

file1.c ha char A[100];

file2.c ha __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. 
+0

Funziona bene. Grazie. –