gpt4 book ai didi

c++ - 函数调用中的堆栈分配

转载 作者:行者123 更新时间:2023-12-03 07:57:15 25 4
gpt4 key购买 nike

当您调用函数时,如果传递给函数的参数不是数组,或者不是有意使用与号 (&) 符号按引用传递,则这些参数将按值传递。例如,

void boo (int a, int b) {}

int main() {
int var1 {1};
int var2 {2};

boo(var1,var2);

return 0;
}

在此场景中,整型变量 var1var2 的值被复制到函数参数 ab 并存储在为 boo() 函数分配的堆栈帧中。我的问题是:

如果我写

void boo (int a, int b) {}

int main() {
boo(1,2);

return 0;
}

整数文字12是否未存储在main()堆栈帧中,因为它们现在是右值?

如果我改为写

void boo (int &a, int &b) {}

int main() {
int var1{1};
int var2{2};

boo(var1,var2);

return 0;
}

参数ab仍然作为某种后台存储在boo()函数的堆栈帧中吗?或者它们现在只是对实际参数 var1var2 的引用?

最佳答案

您编写的代码不是针对您的CPU的指令。它是针对您的编译器的说明。阅读此答案后,您可能会说您的代码只是一个简化的示例,但与您的编译器相同,我只能使用您提供的内容。编译器将您的代码转换为机器指令,这些指令具有 C++ 标准中为您的代码指定的可观察行为。

您的代码:

void boo (int a, int b) {
}

int main() {

int var1 {1};
int var2 {2};

boo(var1,var2);

return 0;
}

与此具有完全相同的可观察行为:

int main() {}

整数文字不得存储在任何地方。它们甚至不需要出现在可执行二进制文件中。对于代码中的其他代码示例也是如此。欲了解更多详情,请参阅What exactly is the "as-if" rule?Storage of literal constants in c++ .


为了便于说明,请考虑一个不同的示例:

int main() {
return [](int x){
int sum = 0;
for (int i=0;i<x;++i) sum += i;
return sum;
}(5);
}

我希望它足以证明打开优化的 gcc 会产生以下输出,而不是在语言律师的基础上讨论它:

main:
mov eax, 10
ret

文字5没有存储在任何地方。如果您愿意,可以尝试将 int x = 5; 传递给 lambda,这不会产生任何影响。正如 PaulMcKenzie 在评论中提到的,您可以将带有循环的 lambda 转换为递归函数,您仍然会看到相同的效果:任何地方都没有 5

Gcc 正确地认识到上述代码的可观察行为是(用简单的英语术语):“从 main 返回 10”,因此它产生了执行此操作的输出。现在你问“5 存储在哪里?”但该代码只是描述从 main 返回 10 的复杂方式,并且不需要在任何地方存储 5

关于c++ - 函数调用中的堆栈分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75736567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com