¿Se aplica la directiva __attribute__ a todos los miembros declarados en una línea?
int a, b, c;Declara tres variables int.
int *a, b, c;Declara la variable "a" como un puntero a int, y b y c como int.
int __attribute__((used)) a, b, c; ¿El atributo used se aplica a todas las variables o solo a ?
Una lista de especificadores de atributos puede aparecer inmediatamente antes de un declarador (que no sea el primero) en una lista de declaradores separados por comas en una declaración de más de un identificador utilizando una sola lista de especificadores y calificadores. Dichos especificadores de atributos se aplican solo al identificador ante cuyo declarador aparecen. por ejemplo, en
__attribute__((noreturn)) void d0 (void),
__attribute__((format(printf, 1, 2))) d1 (const char *, ...), d2 (void);el atributo
noreturnse aplica a todas las funciones declaradas; el atributo de formato solo se aplica ad1.
Corrección : como señala el comentario, mi conclusión anterior es incorrecta. No me di cuenta de la otra que la primera parte.
Conclusión modificada:
En ambos
int __attribute__((used)) a, b, c;y
__attribute__((used)) int a, b, c;El atributo se aplica a todo a, b y c.
Pero si fuera:
int a, __attribute__((used)) b, c; El atributo se aplicaría solo a b .
La documentación de gcc ( 6.36 Sintaxis de atributos ) dice que solo se aplica al identificador ante cuyo declarador aparecen :
Una lista de especificadores de atributos puede aparecer inmediatamente antes de un declarador (que no sea el primero) en una lista de declaradores separados por comas en una declaración de más de un identificador utilizando una sola lista de especificadores y calificadores. Dichos especificadores de atributos se aplican solo al identificador ante cuyo declarador aparecen. por ejemplo, en
__attribute__((noreturn)) void d0 (void), __attribute__((format(printf, 1, 2))) d1 (const char *, ...), d2 (void);
Así que en tu ejemplo:
int __attribute__((used)) a, b, c; el atributo solo se aplica a a .
Refiriéndose al documento GCC ,
La palabra clave
__attribute__le permite especificar atributos especiales al hacer una declaración. Esta palabra clave va seguida de una especificación de atributo entre paréntesis dobles. Nueve atributos, noreturn, const, format, no_instrument_function, section, constructor, destructor, unused y débil están actualmente definidos para las funciones. Se admiten otros atributos, incluida la sección, para declaraciones de variables (consulte la sección 4.29 Especificación de atributos de variables) y para tipos (consulte la sección 4.30 Especificación de atributos de tipos).
Sección 4.29: Atributos de Variables
no usado:
Este atributo, adjunto a una variable, significa que la variable posiblemente no se use. GNU CC no generará una advertencia para esta variable.
Sección 4.30: Atributos de Tipos
no usado:
Cuando se adjunta a un tipo (incluida una unión o una estructura), este atributo significa que las variables de ese tipo deben aparecer posiblemente sin usar. GNU CC no generará una advertencia para ninguna variable de ese tipo, incluso si la variable parece no hacer nada. Este suele ser el caso con las clases de bloqueo o subproceso, que generalmente se definen y luego no se hace referencia a ellas, pero contienen constructores y destructores que tienen funciones de contabilidad no triviales.