在这个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++;节目? 我有以下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生成以下代码(见下文) 请注意,由于您通过返回对局

该标准从函数、控制流、本地对象、堆对象和静态对象等方面进行讨论

<> P>完全可以为一个没有堆栈的体系结构编写C++编译器(旧TMS 9900系列芯片,当我是一个十几岁的青少年时,我就死记硬背)。 你的问题最好是:

在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,但是我应该帮助你。