【发布时间】:2018-03-22 17:43:34
【问题描述】:
编译下面的C模块
static const int i = 1;
void f (const int *i);
int g (void)
{
f (&i);
return i;
}
在 x86_64 处理上使用 gcc -S -O3 会为函数 g 生成以下程序集:
g:
leaq i(%rip), %rdi
subq $8, %rsp
call f@PLT
movl $1, %eax # inlined constant as an immediate
addq $8, %rsp
ret
换句话说,return 语句被编译为将常量$1 移动到返回寄存器%eax,这是有道理的,因为i 被声明为常量。
但是,如果我删除那个 const 以便我拥有
static int i = 1;
void f (const int *i);
int g (void)
{
f (&i);
return i;
}
gcc -S -O3 的输出突然变成:
g:
leaq i(%rip), %rdi
subq $8, %rsp
call f@PLT
movl i(%rip), %eax # reload i
addq $8, %rsp
ret
即在调用f之后,显式地从内存中加载返回值。
为什么会这样? f 的参数被声明为指向常量 int 的指针,因此不应允许 f 更改 i。此外,f 无法通过非常量引用调用修改 i 的函数,因为唯一的此类函数可能是 g,因为 i 被声明为静态。
【问题讨论】:
标签: c gcc assembly compiler-optimization