Con*_*mer 2 c++ pass-by-reference pass-by-value
当您调用函数时,如果传递给函数的参数不是数组,或者不是有意使用与符号 ( ) 进行引用传递,则这些参数将按值传递&。例如,
void boo (int a, int b) {}
int main() {
int var1 {1};
int var2 {2};
boo(var1,var2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,整型变量var1和的值var2被复制到函数参数a和 ,b并存储在为函数分配的堆栈帧中boo()。我的问题是:
如果我写
void boo (int a, int b) {}
int main() {
boo(1,2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是整数文字1并且2不存储在main()堆栈帧中,因为它们现在是右值?
如果我改为写
void boo (int &a, int &b) {}
int main() {
int var1{1};
int var2{2};
boo(var1,var2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是参数a并且b仍然存储在函数的堆栈帧中boo()作为某种备份等。或者它们现在只是对实际参数的var1引用var2?
您编写的代码不是针对您的CPU的指令。它是针对您的编译器的说明。阅读此答案后,您可能会说您的代码只是一个简化的示例,但与您的编译器相同,我只能使用您提供的内容。编译器将您的代码转换为机器指令,这些指令具有 C++ 标准中为您的代码指定的可观察行为。
你的代码:
void boo (int a, int b) {
}
int main() {
int var1 {1};
int var2 {2};
boo(var1,var2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
具有与此完全相同的可观察行为:
int main() {}
Run Code Online (Sandbox Code Playgroud)
整数文字不得存储在任何地方。它们甚至不需要出现在可执行二进制文件中。对于代码中的其他代码示例也是如此。有关更多详细信息,请参阅“假设”规则到底是什么?以及C++ 中文字常量的存储。
为了便于说明,请考虑一个不同的示例:
int main() {
return [](int x){
int sum = 0;
for (int i=0;i<x;++i) sum += i;
return sum;
}(5);
}
Run Code Online (Sandbox Code Playgroud)
我希望它足以证明打开优化的 gcc 会产生以下输出,而不是在语言律师的基础上讨论它:
main:
mov eax, 10
ret
Run Code Online (Sandbox Code Playgroud)
文字5不存储在任何地方。如果您愿意,可以尝试传递int x = 5;给 lambda,这不会产生任何影响。正如 PaulMcKenzie 在评论中提到的那样,您可以将带有循环的 lambda 转换为递归函数,您仍然会看到相同的效果:没有5任何地方。
Gcc 正确地认识到上述代码的可观察行为是(用简单的英语术语):“从 main 返回 10”,因此它产生了这样做的输出。现在你问“存储在哪里5?” 但代码只是一种描述返回的复杂方式10,main不需要5存储在任何地方。