2015-07-26 12 views
5
#include <stdio.h> 

// xyz will be emitted with -flto (or if it is static) even when 
// the function is unused 

__attribute__((__used__)) 
void xyz() { 
    printf("Hello World!\n"); 
} 

int main() { 
    return 0; 
} 

Per cosa ho bisogno?Qual è l'utilizzo dell'attributo usato di gcc?

C'è qualche modo che potrei ancora raggiungere xyz in qualche modo oltre a chiamare direttamente la funzione, come alcuni dlsym() come la magia?

+4

'dlsym' non è la risposta che stai cercando? È confusionario menzionare la risposta in questo modo, proprio nella domanda. – Potatoswatter

+1

Suppongo che potresti avere chiamate a 'xyz' nascoste in linea asm di cui il compilatore non sa nulla. – melpomene

+0

@Potatoswatter: No, non lo è. 'dlsym()' non funziona per gli eseguibili, ecco perché ho scritto "like some". – Thomas

risposta

7

L'attributo used è utile quando si desidera forzare il compilatore a emettere un simbolo, quando normalmente può essere omesso. Come dice GCC's documentation (enfasi mia):

Questo attributo, attaccato ad una funzione, significa che il codice deve essere emessa per la funzione anche se risulta che la funzione non è riferimento. Questo è utile, ad esempio, , quando la funzione è a cui si fa riferimento solo nell'assieme in linea.

Per esempio, se si dispone di codice come segue:

#include <iostream> 

static int foo(int a, int b) 
{ 
    return a + b; 
} 

int main() 
{ 
    int result = 0; 

    // some inline assembly that calls foo and updates result 

    std::cout << result << std::endl; 
} 

si potrebbe notare, che nessun simbolo foo è presente con -O bandiera (livello di ottimizzazione -O1):

g++ -O -pedantic -Wall check.cpp -c 
check.cpp:3: warning: ‘int foo(int, int)’ defined but not used 
nm check.o | c++filt | grep foo 

Come un risultato non è possibile fare riferimento a foo all'interno di questo assembly (immaginario) in linea.

Aggiungendo:

__attribute__((__used__)) 

si trasforma in:

g++ -O -pedantic -Wall check.cpp -c 
nm check.o | c++filt | grep foo 
00000000 t foo(int, int) 

così ora foo possibile fare riferimento al suo interno.

Potrebbe anche essere stato rilevato che l'avviso di gcc non è più presente, poiché è stato detto al compilatore che si è certi che foo sia effettivamente utilizzato "dietro la scena".