関数などを呼び出しているので、何らかの関数にいると思います。
test
との両方のスペースは、スタックx
に割り当てられます。理論的には、値が入力される前にこれらの人のためのスペースが存在するはずです。生成されたアセンブリ (x86 gcc) を見ると、これは正しいです。
subl $40, %esp # Add 40 bytes of memory to the current stack
movl $0, -20(%ebp) # Clear test[0] to 0
movl $0, -16(%ebp) # Clear test[1] to 0
movl $45, -20(%ebp) # Place the value of 45 into test[0]
movl -20(%ebp), %eax # Copy that 45 into a register
movl %eax, -16(%ebp) # Move that register's value (45) into test[1]
movl $111, -12(%ebp) # Assign x to be 111, optimize out the unnecessary duplicate assignment
... #continues on to set up and call printf
スタックに 40 バイトが追加されていることがわかります。%ebp
test[0]、test[1]、および x のアドレスはすべて、4 バイト間隔 (それぞれ -20、-16、-12) でマークされた連続したアドレスであることに注意してください。メモリ内のそれらの場所は存在し、定義される前にエラーなしでアクセスできます。ここでコンパイラは両方を 0 にクリアしますが、これは不要であることがわかります。これらの 2 行を削除しても問題なく実行できます。
ここから導き出せることは、あなたのint test[2]とint xは、それ自体の中にファンキーな循環参照をいくつでも持つことができ、コードがコンパイルされるということです.あなたの仕事は、参照が適切なデータを確実に取得することです(つまり、何らかの方法で初期化されたデータ) )、ここで行ったガベージではありません。これは他のケースでも機能します - アセンブリにコンパイルし、それがどのように行われたかを自分で確認してください。