2015-06-26 34 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))

相关问题