以下に示すコードの場合、住所を印刷すると次のようになります。プログラムはここでどのようにスタックを使用していますか?
&test_var1 = 0x7fff0067d87c
&barrier (passed argument) = 0x7fff0067d770
&i (passed argument) = 0x7fff0067d77c
&test_var2 = 0x7fff0067d78c
私がここで理解していない2つのことがあります。まず、Cが右から左に引数をプッシュし、次に& iが&のバリアよりも大きいことを読んでいます。スタックが上位アドレスから下位アドレスに増加することを知り、& iは、より低いアドレスにあるはずです。さらに、ローカル変数test_var2はさらに大きなアドレスにあります。
第二に、人は一緒に近いことが&バリアと& test_var1の値を期待するだろうが、いいえ、あなたは、268バイトの大きな違いを参照してください。その間にあるスタックは何ですか?
私は最適化O3を使用していることに注意してください。これが原因ですか?多分コンパイラがここでいくつかのトリックを果たしたでしょうか?私はvolatileを使用して、すべての変数がここにスタックにあり、いくつかのレジスタにキャッシュされていないことを確認します。
void some_func()
{
.........
{
volatile int test_var1 = 0;
}
call_func(i, &barrier);
........
}
void call_func(volatile int i, volatile pthread_barrier* barrier)
{
volatile int test_var2 = 0;
........
}
スタックの使用方法は、特定のCコンパイラで実装されています。あなたはあなたのケースでGCCソースでこれを見ることができます。 –
コンパイルして実行できる完全な例を含めると、私たちにとってもっと簡単になります。 – NPE
'volatile'は変数の*アドレス*に影響しません。 'volatile int'はint自体が変更可能であることを意味しますが、' volatile whatever * 'は 'volatile'であることを意味しますが、ポインタ(すなわち変数)自体はvolatileではありません - もう一方の方法は 'whatever volatile * 'です。 – ams