函数如何在不使用 malloc 的情况下返回结构?

amj*_*jad 1 c struct allocation return-value

我是 C 新手,只是一个关于返回结构的问题。我听到有人说可以返回一个结构体。例如:

struct MyObj{
   int x,y,z;
};

struct MyObj foo(){
    struct MyObj foo_a;
    foo_a.x = 10;
    foo_a.y = 10;
    foo_a.z = 10;

    return foo_a;
}        

int main () {
    struct MyObj main_a = foo();
    return 0;
} 
Run Code Online (Sandbox Code Playgroud)

我的问题是:

foo_afoo的堆栈,在经过这么foo结束,堆栈将unwinded,其手段foo_a实际上并不存在的main函数的栈指针main_amain持有实际上是一个非法的指针,那么它是怎么样的工作?

Eri*_*hil 5

一种常见的实现方式是调用例程为结构分配一些空间,通常在堆栈上,并将指向该空间的指针传递给被调用例程。这个参数在 C 源代码中看不到——它是如何在汇编语言中调用例程的调用约定的一部分。然后被调用的例程简单地将结构的内容存储在指向的空间中。

换句话说,代码的实现在很大程度上就像是这样写的:

void foo(struct MyObj *temporary){
    struct MyObj foo_a;
    foo_a.x = 10;
    foo_a.y = 10;
    foo_a.z = 10;
    *temporary = foo_a;
}        

int main () {
    struct MyObj temporary;
    foo(&temporary);
    struct MyObj main_a = temporary;
    return 0;
} 
Run Code Online (Sandbox Code Playgroud)

如果结构很小,它可以在一个寄存器或几个寄存器中返回。被调用例程和调用例程都将使用相同的调用约定,这将具有关于哪些结构在寄存器中返回,哪些结构通过调用者提供的指向返回的规则。