__attribute__是否适用于声明中的所有变量?

时间:2015-06-26 07:22:49

标签: c gcc

__attribute__指令是否适用于在一行上声明的所有成员?

int a, b, c;

声明三个int变量。

int *a, b, c;

将变量“a”声明为int的指针,将b和c声明为int。

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

used属性是应用于所有变量还是仅适用于a

4 个答案:

答案 0 :(得分:28)

来自GCC: Attribute-Syntax

  

属性说明符列表可以使用单个说明符和限定符列表,在多个标识符的声明中以逗号分隔的声明符列表中的声明符(不是第一个)之前出现。这些属性说明符仅适用于它们出现在其声明符之前的标识符。例如,在

__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;

该属性适用于所有abc

答案 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))也是如此。