2015-06-26 4 views
33

Gilt die Richtlinie __attribute__ für alle in einer Zeile deklarierten Mitglieder?Gilt __attribute__ für alle Variablen in einer Deklaration?


int a, b, c; 

Deklariert drei int-Variablen.


int *a, b, c; 

Erklärt Variable "a" als ein Zeiger auf int und b und c als Int.


int __attribute__((used)) a, b, c; 

Ist die used auf alle Variablen gelten Attribut oder nur a?

+11

Sie könnten das wahrscheinlich testen. Attribute sind nicht Teil des C-Standards, daher kann jeder Compiler tun, was er will. Erstellen Sie einfach ein einfaches Programm wie Sie es haben, verknüpfen Sie es und machen Sie einen Dump der Symbole. –

+5

Aus demselben Grund ist die Pointer-Deklaration vage (d. H. 'Int * a, b;' deklariert b nicht als Zeiger), es wird im Allgemeinen empfohlen, NIE mehr als eine Variable pro Zeile zu deklarieren. Dann gibt es keine Zweideutigkeit. Gleiches gilt für '__attributes__' –

+0

Nun, die Frage ist, ob das' __attribute__' den Typ (linke Seite) oder die Variable (rechte Seite) beeinflusst. Da 'used' ist ein variables Attribut [https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes] und kein Typattribut [https: //gcc.gnu. org/onlinedocs/gcc/Common-Type-Attribute.html # Common-Type-Attribute] sollte nur die Variable 'a' betreffen. – harper

Antwort

29

Von GCC: Attribute-Syntax:

Ein Attribut Spezifikationsliste kann erscheint unmittelbar vor einem Deklarator (anders als der erste) in einer kommagetrennten Liste von Deklaratoren in einer Deklaration von mehr als einem Bezeichner unter Verwendung einer einzigen Liste von Bezeichnern und Qualifiern. Solche Attributbezeichner gelten nur für die Kennung, vor deren Deklarator sie erscheinen. Zum Beispiel in

__attribute__((noreturn)) void d0 (void), 
    __attribute__((format(printf, 1, 2))) d1 (const char *, ...), 
     d2 (void); 

das noreturn Attribut gilt für alle Funktionen erklärt; Das Format-Attribut gilt nur für d1.

zu Demnach, in Ihrem Beispiel:

int __attribute__((used)) a, b, c; 

Das Attribut gilt nur für a.

Aber wenn es waren:

__attribute__((used)) int a, b, c; 

Das Attribut gilt für alle a, b und c.

9

gcc Dokumentation (6.36 Attribute Syntax) sagt, es gilt nur auf die Kennung vor dessen declarator sie erscheinen:

Ein Attribut Spezifikationsliste unmittelbar vor einem declarator erscheinen (außer dem ersten) in einer komma getrennte Liste von Deklaratoren in einer Deklaration von mehr als einem Bezeichner unter Verwendung einer einzigen Liste von Bezeichnern und Qualifiern. Solche Attributbezeichner gelten nur für die Kennung, vor deren Deklarator sie erscheinen. Zum Beispiel in

__attribute__((noreturn)) void d0 (void), 
    __attribute__((format(printf, 1, 2))) d1 (const char *, ...), 
     d2 (void); 

So in Ihrem Beispiel:

int __attribute__((used)) a, b, c; 

das Attribut gilt nur für a.

3

Bezug das GCC document,

Das Schlüsselwort __attribute__ können Sie spezielles Attribut angeben, wenn eine Erklärung abgeben. Auf dieses Schlüsselwort folgt eine Attributspezifikation in doppelten Klammern. Für Funktionen sind derzeit neun Attribute, noreturn, const, format, no_instrument_function, section, constructor, destructor, unused und weak definiert. Andere Attribute, einschließlich Abschnitt, werden für Variablendeklarationen (siehe Abschnitt 4.29 Spezifizieren von Variablenattributen) und für Typen (siehe Abschnitt 4.30 Spezifizieren von Attributen von Typen) unterstützt.

Section 4.29: Attributes of Variables

ungenutzten:
Dieses Attribut, auf Variable gebunden bedeutet, dass die Variable möglicherweise nicht benutzt werden gemeint ist. GNU CC wird keine Warnung für diese Variable erzeugen.

Section 4.30: Attributes of Types

ungenutzt:
Bei einem Typ angebracht (einschließlich einer Gewerkschaft oder einer Struktur), bedeutet dieses Attribut, dass Variablen dieses Typs möglicherweise ungenutzt erscheinen sollen. GNU CC wird keine Warnung für irgendwelche Variablen dieses Typs erzeugen, auch wenn die Variable scheinbar nichts tut.Dies ist häufig der Fall mit Schloss oder Gewindeklassen, die in der Regel definiert sind und dann nicht referenziert, sondern enthalten Konstruktoren und Destruktoren, die nicht-triviale Funktionen

Buchhaltung haben
3

Die Antwort ist, dass das Attribut wahrscheinlich nichts tut.

$ cat f.c 
int foo_f1; 
int __attribute__((used)) foo_f2; 

main() 
{ 
} 

und

$ cat g.c 
int foo_g1; 
int __attribute__((used)) foo_g2; 

build f als OBJ, g als Bibliothek

$ gcc -c -o g.o g.c 
$ ar rs libg.a g.o 
$ gcc -O3 f.c -lg 

$ objdump.exe -t a.exe | grep foo 
[532](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000100 _foo_f1 
[599](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000104 _foo_f2 

Grundsätzlich hat der Linker keine Symbole aus f.c entfernen und entfernt alles von g.c, auch mit die __attribute__((used)).

Verwandte Themen