__attribute__
指令是否适用于在一行上声明的所有成员?
int a, b, c;
声明三个int变量。
int *a, b, c;
将变量“a”声明为int的指针,将b和c声明为int。
int __attribute__((used)) a, b, c;
used
属性是应用于所有变量还是仅适用于a
?
答案 0 :(得分:28)
属性说明符列表可以使用单个说明符和限定符列表,在多个标识符的声明中以逗号分隔的声明符列表中的声明符(不是第一个)之前出现。这些属性说明符仅适用于它们出现在其声明符之前的标识符。例如,在
中__attribute__((noreturn)) void d0 (void), __attribute__((format(printf, 1, 2))) d1 (const char *, ...), d2 (void);
noreturn
属性适用于声明的所有函数; format属性仅适用于d1
。
根据这个,在你的例子中:
int __attribute__((used)) a, b, c;
该属性仅适用于a
。
但如果是:
__attribute__((used)) int a, b, c;
该属性适用于所有a
,b
和c
。
答案 1 :(得分:8)
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
。
答案 2 :(得分:2)
参考GCC document,
关键字
__attribute__
允许您在进行声明时指定特殊属性。此关键字后面是双括号内的属性规范。目前为函数定义了九个属性,noreturn,const,format,no_instrument_function,section,constructor,析构函数,unused和weak。其他属性(包括section)支持变量声明(参见4.29指定变量属性)和类型(参见4.30指定类型属性)。
Section 4.29: Attributes of Variables
未使用:
附加到变量的此属性表示该变量可能未使用。 GNU CC不会对此变量发出警告。
Section 4.30: Attributes of Types
未使用:
当附加到类型(包括联合或结构)时,此属性意味着该类型的变量可能看起来可能未使用。即使变量似乎什么都不做,GNU CC也不会对该类型的任何变量发出警告。这通常是锁定或线程类的情况,这些类通常被定义然后不被引用,但包含具有重要簿记功能的构造函数和析构函数
答案 3 :(得分:2)
答案是该属性可能没有做任何事情。
$ 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))
也是如此。