在这个c++;节目? 我有以下C++程序,其中一个函数返回对局部变量的引用。你能一步一步地告诉我堆栈到底发生了什么吗 #include<stdio.h> double& init_pi() { double pi = 3.14; return pi; } double circumference(double r, double& pi) { printf("%lf\n", pi); return 2*r*pi; } int main() { printf("%lf\n,", circumference(2, init_pi())); return 0; } #包括 double&init_pi() { 双pi=3.14; 返回pi; } 双周长(双r、双P和pi) { printf(“%lf\n”,pi); 返回2*r*pi; } int main() { printf(“%lf\n”,周长(2,init_pi()); 返回0; } 谢谢你的回答。 与流行的信念相反,C++标准从来没有提到堆栈的概念。(除了std::stack类模板之外,这里不是指std::stack类模板)
该标准从函数、控制流、本地对象、堆对象和静态对象等方面进行讨论 <> P>完全可以为一个没有堆栈的体系结构编写C++编译器(旧TMS 9900系列芯片,当我是一个十几岁的青少年时,我就死记硬背)。 你的问题最好是:在这个c++;节目? 我有以下C++程序,其中一个函数返回对局部变量的引用。你能一步一步地告诉我堆栈到底发生了什么吗 #include<stdio.h> double& init_pi() { double pi = 3.14; return pi; } double circumference(double r, double& pi) { printf("%lf\n", pi); return 2*r*pi; } int main() { printf("%lf\n,", circumference(2, init_pi())); return 0; } #包括 double&init_pi() { 双pi=3.14; 返回pi; } 双周长(双r、双P和pi) { printf(“%lf\n”,pi); 返回2*r*pi; } int main() { printf(“%lf\n”,周长(2,init_pi()); 返回0; } 谢谢你的回答。 与流行的信念相反,C++标准从来没有提到堆栈的概念。(除了std::stack类模板之外,这里不是指std::stack类模板),c++,stack,C++,Stack,该标准从函数、控制流、本地对象、堆对象和静态对象等方面进行讨论 P>完全可以为一个没有堆栈的体系结构编写C++编译器(旧TMS 9900系列芯片,当我是一个十几岁的青少年时,我就死记硬背)。 你的问题最好是: 在C++编译器中,如何用X编译器编译,一个一步一步地改变堆栈? 答案只在调试器或汇编程序列表中(对于gcc,使用-S选项编译) 事实上,如果您编译这个程序时启用了优化,那么就根本不会有堆栈移动。整个流程将内联 例如,gcc 5.3和-O2生成以下代码(见下文) 请注意,由于您通过返回对局
在C++编译器中,如何用X编译器编译,一个一步一步地改变堆栈? 答案只在调试器或汇编程序列表中(对于gcc,使用-S选项编译)
事实上,如果您编译这个程序时启用了优化,那么就根本不会有堆栈移动。整个流程将内联 例如,gcc 5.3和-O2生成以下代码(见下文) 请注意,由于您通过返回对局部变量的引用引入了未定义的行为,因此允许编译器执行任何它喜欢的操作。在本例中,它决定您的程序不执行任何操作。main只返回零 汇编程序输出:init_pi():
xorl %eax, %eax
ret
.LC1:
.string "%lf\n"
circumference(double, double&):
pushq %rbx
movl $1, %eax
movq %rdi, %rbx
subq $16, %rsp
movsd %xmm0, 8(%rsp)
movsd (%rdi), %xmm0
movl $.LC1, %edi
call printf
movsd 8(%rsp), %xmm1
movsd (%rbx), %xmm0
addq $16, %rsp
addsd %xmm1, %xmm1
popq %rbx
mulsd %xmm1, %xmm0
ret
main:
movsd 0, %xmm0
ud2
编译器警告:
/tmp/gcc-explorer-compiler11636-75-1libuwy/example.cpp: In function 'double& init_pi()':
5 : warning: reference to local variable 'pi' returned [-Wreturn-local-addr]
double pi = 3.14;
^
Compiled ok
如果我们修复了警告和后续错误,我们将得到以下结果:
init_pi():
movsd .LC0(%rip), %xmm0
ret
.LC2:
.string "%lf\n"
circumference(double, double):
subq $24, %rsp
movl $.LC2, %edi
movl $1, %eax
movsd %xmm0, 8(%rsp)
movapd %xmm1, %xmm0
movsd %xmm1, (%rsp)
call printf
movsd 8(%rsp), %xmm2
movsd (%rsp), %xmm1
addq $24, %rsp
addsd %xmm2, %xmm2
movapd %xmm2, %xmm0
mulsd %xmm1, %xmm0
ret
.LC5:
.string "%lf\n,"
main:
subq $8, %rsp
movl $.LC2, %edi
movl $1, %eax
movsd .LC0(%rip), %xmm0
call printf
movsd .LC4(%rip), %xmm0
movl $.LC5, %edi
movl $1, %eax
call printf
xorl %eax, %eax
addq $8, %rsp
ret
.LC0:
.long 1374389535
.long 1074339512
.LC4:
.long 1374389535
.long 1076436664
同样,您将看到
main
已完全内联。堆栈没有任何用途(除了在调用printf期间)就像计算机如何一步一步地计算这个一样?是的。我知道这段代码是不正确的,我也知道为什么不正确,但我想看看“幕后”到底发生了什么,以便完全理解堆栈的工作原理以及这段代码是如何导致问题的。你可以通过调试自己完成。@KarthikeyanVaithilingam我怎么做?@DavidHerskovics我从未使用过code::Blocks,但是我应该帮助你。