#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; }¿Para qué necesito esto?
¿Hay alguna forma en que pueda llegar a xyz de alguna manera además de llamar directamente a la función, como algunos dlsym() como magia?
El atributo used es útil en situaciones en las que desea forzar al compilador a emitir un símbolo, cuando normalmente se puede omitir. Como dice la documentación de GCC (énfasis mío):
Este atributo, adjunto a una función, significa que se debe emitir código para la función incluso si parece que no se hace referencia a la función. Esto es útil, por ejemplo, cuando se hace referencia a la función solo en ensamblado en línea .
Por ejemplo, si tiene un código de la siguiente manera:
#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; } puede notar que no hay ningún símbolo foo con el indicador -O (nivel de optimización -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 Como resultado, no puede hacer referencia a foo dentro de este ensamblaje en línea (imaginario).
Añadiendo:
__attribute__((__used__))se convierte en:
g++ -O -pedantic -Wall check.cpp -c nm check.o | c++filt | grep foo 00000000 t foo(int, int) por lo tanto, ahora se puede hacer referencia a foo dentro de él.
Es posible que también hayas notado que la advertencia de gcc ya no existe, ya que le has dicho a tu compilador que estás seguro de que foo se usa realmente "detrás de escena".
Un caso de uso particular es para las rutinas de servicio de interrupción en una biblioteca estática. Por ejemplo, una interrupción de desbordamiento de temporizador:
void __attribute__((interrupt(TIMERA_VECTOR),used)) timera_isr(void)
Este timera_isr nunca es llamado por ninguna función en el código de usuario, pero puede formar una parte esencial de una biblioteca. Para garantizar que esté vinculado y que no haya un vector de interrupción que apunte a una sección vacía, la palabra clave garantiza que el vinculador no lo optimice.
Si declara una variable global o una función que no se usa, gcc la optimizará (con una advertencia), pero si declaró la variable global o la función con '__attribute__((used))' , gcc la incluirá en el archivo de objeto ( y ejecutable vinculado).
https://gcc.gnu.org/legacy-ml/gcc-help/2013-09/msg00108.html