普遍的な信念とは対照的に、C++標準ではスタックという概念は決して言及されていません。 (std :: stackクラス以外のテンプレートはここでは意味しません)。
この標準では、機能、制御の流れ、ローカルオブジェクト、ヒープオブジェクト、および静的オブジェクトに関して言及しています。
スタックを持たないアーキテクチャ(私がティーンエージャーだったときに私が使用していた古いTMS 9900シリーズのチップ)には、C++コンパイラを書くことは全く可能です。
Zアーキテクチャ用のYオプションを使用して、Xコンパイラでコンパイルするとき、このC++プログラムにステップすることにより、スタック変更ステップをどのよう
:あなたの質問は、より良いよう
を置くかもしれませんか?真実の答が(gccのために、-Sオプションでコンパイル)リストのみデバッガやアセンブラで横たわるため
、あなたが最適化して、このプログラムをコンパイルする場合、ノーがあるでしょうスタックの動きは全くありません。フロー全体がインライン展開されます。
には、例えば、-O2とGCC 5.3を使用すると、ローカル変数への参照を返すことによって未定義の動作を導入しているため、コンパイラはそれが好きで何かをすることが許可されていること(下記参照)
注次のコードを生成します。この場合、あなたのプログラムは何もしないと決めました。 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の呼び出し中以外)
コンピュータがこの手順をステップごとにどのように計算するのか? – theblindprophet
はい。私は、このコードは正しくないと分かっていますが、なぜそうではないのか一般的な考え方を持っていますが、スタックの仕組みとそのコードがどのように問題を引き起こすかを完全に理解するために、 –
あなたは自分でデバッグします。 –