C 赋值给变量vs立即使用返回值

C 赋值给变量vs立即使用返回值,c,assembly,C,Assembly,与测试中c的显式赋值相比,test2中add(a,b)的返回值会发生什么变化 void test(int a,int b) { int c=add(a,b); return incr(c); } void test2(int a,int b) { return incr(add(a,b)); } 在字节码的实现中,即对于JVM、AVM2和Javascript解释器/JIT,通过引用/值进行赋值在理论上是相同的 可能命名值(变量)和未命名值都是指向堆栈中上下文位置的独立指

与测试中c的显式赋值相比,test2中add(a,b)的返回值会发生什么变化

void test(int a,int b) {
    int c=add(a,b);
    return incr(c);
}
void test2(int a,int b) {
    return incr(add(a,b));
}
在字节码的实现中,即对于JVM、AVM2和Javascript解释器/JIT,通过引用/值进行赋值在理论上是相同的

可能命名值(变量)和未命名值都是指向堆栈中上下文位置的独立指令。也就是说,没有神奇的优化将返回值抛到下一条指令中

也就是说,
test2
中的
incr
指令仍然会导致堆栈的
incr第三个值
或类似的结果。

答案是“这取决于”。在您正在使用的编译器上,以及在与编译器一起使用的选项上(编译以获得最佳可调试性,而不是最佳性能)

在优化模式下,一个体面的现代编译器会意识到变量
c
仅在
return
语句中立即使用一次,并且只会将该值保留在堆栈顶部,这样就可以对其进行
return
编辑


在调试模式下,通常会关闭该优化,并将该值分配给名为
c
的实变量,该变量占用堆栈帧中的一个插槽。这允许您在该行之后暂停并检查值,以查看在执行返回之前分配给它的内容。它需要更多的周期,但由于这不是您通常用于发送给“客户”的代码或用于性能分析的模式,除了编译器/调试器作者之外,其他人通常都不关心这些模式。

根据优化情况,这可能没有什么区别。这是一个编译器的东西。这两者之间的区别并不是由C定义的。检查编译器自己生成的代码(发布版本)。你会发现它们完全一样!我很惊讶在编程课上,他们谈论的是无意义的优化,而不是更容易阅读和理解的内容!!!:你认为命名的临时变量很昂贵吗?您认为产生费用的单位是什么?为什么成本对您很重要?您是否认为仅仅因为存储位置没有名称,它就不存在?
add
的结果必须在某个地方;如果你没有给那个位置起名字,它仍然存在。没有“临时变量”这样的东西。变量总是有名称的,因此不是临时的。还有一些临时值,比如表达式
add(a,b)
.CS104(C)的值,AP类只是讨论指针的理论实现、数组内存访问、字符数组与惯性。我不知道它是否昂贵。这一直是我的问题,因为我不懂组装。我对以下行为很好奇:按值赋值和本机代码指针(在JVM、AVM2和Javascript解释器/JIT中按引用赋值)。