gcc __attribute__ 放置之间的区别

abj*_*shi 0 c gcc gcc-extensions

在为函数使用 gcc __attribute__ 时,我注意到代码生成存在差异,具体取决于我放置属性的位置。在下面的示例中,我希望编译器不要优化我对 use() 的调用。

编译器:x86-64 gcc(trunk)

选项:-O3 -Wall

void  __attribute__((noinline, optimize("O0"))) use() {} 
int main () 
{
    use();
}
use:
        push    rbp
        mov     rbp, rsp
        nop
        pop     rbp
        ret
main:
        xor     eax, eax
        call    use
        xor     eax, eax
        ret
Run Code Online (Sandbox Code Playgroud)

但是,如果我更改属性的位置,则会生成不同的代码。

void   use() {} __attribute__((noinline, optimize("O0")))
int main () 
{
    use();
}
main:
        push    rbp
        mov     rbp, rsp
        mov     eax, 0
        pop     rbp
        ret
use:
        ret
Run Code Online (Sandbox Code Playgroud)

如果我不放任何属性,我会得到这个:

void   use() {} 
int main () 
{
    use();
}
use:
        ret
main:
        xor     eax, eax
        ret
Run Code Online (Sandbox Code Playgroud)

现在,我在gcc_Common-Function-Attributes中看到的属性都出现在函数声明中,而不是定义中。我不确定我是否应该只在声明中使用它们。(因为在定义中使用它们似乎在上面的一个实例中工作)我的问题是 __attribute__ 的放置规则是什么,为什么上面的行为方式是这样的?我检查了gcc_Attribute-Syntax,但恐怕我不太了解它。

Bar*_*mar 5

__attribute__是其后的函数规范的一部分。你的第二个版本实际上是:

__attribute__((noinline, optimize("O0"))) int main() {
    ...
}
Run Code Online (Sandbox Code Playgroud)

您正在设置main()函数的属性,而不是use()函数。

请记住,newlies 在解析 C 代码时没有任何特殊含义,因此将属性与use()声明放在同一行实际上并不会使其成为其中的一部分。