我比较了两个返回结构体的C函数。我们知道在ABI级别上,大结构体将作为第一个函数参数通过指针传递。
struct S {
int words[8];
};
struct S fsret() {
struct S s;
s.words[0] = 1;
return s;
}
void fout(struct S* s) {
s->words[0] = 1;
}
对于这些函数,我检查了x86_64 Linux和Windows的汇编代码。
fsret
被声明为void @fsret(%struct.S* sret %s)
。比较这两个版本,在被调用方面没有区别。但是,在函数内部,
fsret
另外将其第一个参数(指向结构体的指针)复制到RAX寄存器中。为什么呢?
if (fsret().words[0]==10) { do_something(); }
? 编译器在这种情况下需要一个返回值(不确定,只是一个想法) - Jean-François Fabre