c-变量属性的GCC扩展__attribute__((未使用))



以下是GCC变量属性扩展的示例代码

#include<stdio.h>
int main(void){
int sam __attribute__((unused))= 10;
int p = sam+1;
printf("n%d" , p);
}

对于使用生成的上述程序的汇编代码

gcc -S sample.c

.s文件中不包含变量sam,而程序的输出是"11",这是正确的。那么,编译器是否完全忽略了未使用的变量,而不在可执行文件中输出它?如果是,为什么程序的输出正确?谁能解释一下gcc中未使用和已使用的变量属性的工作原理吗。

感谢

编译器是否完全忽略了未使用的变量

取决于您所说的";忽视";。编译器优化代码,但不会完全忽略变量,否则编译器无法计算结果。

是否在可执行文件中输出?

是。

如果是,为什么程序的输出正确?

因为这就是编译器所做的-生成具有编程语言所述输出的程序。代码不是程序集的1:1,代码是描述程序的行为的语言。理论上,只要编译程序的输出与源代码中的内容正确,编译器就可以生成它想要的任何汇编指令。

您可能想在C编程语言的上下文中研究术语副作用好像规则

任何人都能解释gcc中未使用和已使用的变量属性的工作原理吗。

没有比GCC文档中关于变量属性更好的解释了:

未使用的

此属性附加到变量,表示该变量可能未使用。GCC不会对此变量产生警告。

使用

此属性附加到具有静态存储的变量,意味着即使变量看起来没有被引用,也必须发出该变量。

当应用于C++类模板的静态数据成员时,该属性还意味着,如果类本身被实例化,则该成员被实例化。

属性unused用于从-Wunused-*警告中消除编译器警告。

属性used用于变量(但我认为也适用于函数(,以便将变量生成为汇编代码。即使它在任何地方都没有被使用。

尝试在没有优化的情况下进行编译

gcc -O0 sample.c -S -masm=intel

生成的汇编代码

.file   "sample.c"
.intel_syntax noprefix
.text
.def    __main; .scl    2;  .type   32; .endef
.section .rdata,"dr"
.LC0:
.ascii "12%d"
.text
.globl  main
.def    main;   .scl    2;  .type   32; .endef
.seh_proc   main
main:
push    rbp
.seh_pushreg    rbp
mov rbp, rsp
.seh_setframe   rbp, 0
sub rsp, 48
.seh_stackalloc 48
.seh_endprologue
call    __main
mov DWORD PTR -4[rbp], 10
mov eax, DWORD PTR -4[rbp]
add eax, 1
mov DWORD PTR -8[rbp], eax
mov eax, DWORD PTR -8[rbp]
mov edx, eax
lea rcx, .LC0[rip]
call    printf
mov eax, 0
add rsp, 48
pop rbp
ret
.seh_endproc
.ident  "GCC: (GNU) 10.2.0"
.def    printf; .scl    2;  .type   32; .endef

最新更新