2015-06-26 38 views
33

__attribute__指令是否適用於在一行上聲明的所有成員?__attribute__是否適用於聲明中的所有變量?


int a, b, c; 

聲明由3個int變量。


int *a, b, c; 

聲明變量 「a」 作爲指針爲int,並且b和c爲INT。


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

是否used屬性應用到所有變量或僅a

+11

你也許可以測試這個。屬性不是C標準的一部分,所以每個編譯器都可以做任何他們想要的。只要像你一樣創建一個簡單的程序,鏈接它並做一個符號轉儲。 –

+5

由於同樣的原因,指針聲明是模糊的(即'int * a,b;'沒有聲明b作爲指針),所以一般建議不要每行聲明多個變量。那麼就沒有歧義。同樣適用於'__attributes__' –

+0

那麼問題是如果'__attribute__'影響類型(左側)或變量(右側)。由於'used'是可變屬性[https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes],而不是類型屬性[https://gcc.gnu。 org/onlinedocs/gcc/Common-Type-Attributes.html#Common-Type-Attributes]它應該隻影響變量'a'。 – harper

回答

29

GCC: Attribute-Syntax的情況下:

的屬性說明符列表可出現在聲明者(除第一個之外)之前的一個聲明的逗號分隔的列表中,聲明多個標識符使用單個說明符和限定詞列表。這種屬性說明符只適用於其聲明符出現之前的標識符。例如,在

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

noreturn屬性適用於聲明的所有函數;格式屬性僅適用於d1

根據這一點,在你的榜樣:

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

的屬性只適用於a

但如果它是:

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

屬性適用於所有abc

9

gcc文檔(6.36 Attribute Syntax)說,它僅適用於出現之前,其聲明符標識符:

的屬性說明符列表可能會立即出現一個聲明符之前(除了第)在一個逗號在多個標識符的聲明中使用單個說明符和限定詞列表來區分獨立的聲明符列表。這種屬性說明符只適用於其聲明符出現之前的標識符。例如,在

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

所以在你的例子:

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

屬性僅適用於a

3

參考的GCC document

關鍵字__attribute__允許你指定特殊的屬性聲明時。該關鍵字後面跟着一個雙括號內的屬性規範。當前爲函數定義了9個屬性,noreturn,const,format,no_instrument_function,section,構造函數,析構函數,未使用和弱等。其他屬性(包括段)支持變量聲明(請參見4.29指定變量的屬性)和類型(請參閱4.30指定類型的屬性)。

Section 4.29: Attributes of Variables

未使用:
該屬性,連接到一個變量,表示該變量是指可能不會被使用。 GNU CC不會爲這個變量產生警告。

Section 4.30: Attributes of Types

未使用的:
當連接到一個類型(包括聯合或結構),該屬性表示該類型的變量意味着出現可能未被使用。即使變量看起來什麼也不做,GNU CC不會爲任何類型的變量產生警告。這通常是與鎖或螺紋類,它們通常被定義,然後未被引用,但包含構造和析構具有非平凡簿記功能

3

答案是該屬性可能不會做任何事情。

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

main() 
{ 
} 

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

構建f與obj,g作爲圖書館

$ 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 

基本上,鏈接器並沒有刪除任何f.c符號和從g.c去除一切,甚至用__attribute__((used))

相關問題