@P.P.の答えは正しい:これは未定義の動作です。
実際には、コンパイラの実装に大きく依存します。 最も可能性の高いシナリオは、呼び出し元関数が戻り値をとることです。呼び出し先関数は値を返さないので、呼び出し元関数はスタックから「ランダム」な値を取ることになります。
私は(任意の最適化なし)GCCコンパイラであなたの例を提供するつもりです:
これは機能add
のためのアセンブリコードです:
push %rbp
mov %rsp,%rbp
mov %edi,-0x14(%rbp)
mov %esi,-0x18(%rbp)
mov -0x14(%rbp),%edx
mov -0x18(%rbp),%eax
add %edx,%eax
mov %eax,-0x4(%rbp)
nop
nop
pop %rbp
retq
さらに、あなたが見ることができるように変数がc
に格納されます。 結果値は幸いにも%eax
レジスタに格納されますが、これは目的のために行われていません。あなたが見ることができるように
push %rbp
mov %rsp,%rbp
mov %edi,-0x14(%rbp)
mov %esi,-0x18(%rbp)
mov -0x14(%rbp),%edx
mov -0x18(%rbp),%eax
add %edx,%eax
mov %eax,-0x4(%rbp)
mov -0x4(%rbp),%eax <====
pop %rbp
retq
は、c
に格納された値が正しく%eax
レジスタに移動させる(<====
でマークされた命令で):
ここ正しい機能のアセンブリコードがあります。 main
機能(呼び出し側)で
は、代わりに、アセンブリは次のとおりです。
callq 0x400542 <add>
mov %eax,%ecx
あなたは、呼び出し元の機能を見ることができるように、関数の呼び出しの後、想定している「戻り値」を取ります%eax
に登録してください。
これは、呼び出し元関数が実際に値を返すにもかかわらず、呼び出し元関数は戻り値をとることを意味します。
私があなたに示した例では、呼び出し元が返す戻り値は%eax
です。結論として
呼び出し先機能が適切な値を返さない場合、呼び出し元機能(メイン)は呼び出し先が適切Aを返さない場合は汚れの値とすることができる%eax
レジスタ(に格納されているものとにかくかかりますが値)。
XY問題:なぜあなたはCを返そうとしませんか? –
@ Jean-FrançoisFabre私は、Cが明示的にそれを返すことなく返される方法を知りたがっています。 –