2017-08-25 5 views
8

xyある整数は、このコードを、考えてみましょうか?このコンパイラ変換は許可されていますか?</p> <pre><code>if (x) y = 42; </code></pre> <p>次のコンパイラ変換許可されている:

int tmp = y; 
y = 42; 

if (!x) 
    y = tmp; 

コンテキスト

これはビャーネ・ストロヴストルップのよくある質問からです:

// start with x==0 and y==0 

if (x) y = 1; // Thread 1 

if (y) x = 1; // Thread 2 

よくある質問の状態これが無料のデータ競合です。 xyが両方とも0の場合、いずれの値も書き込まれません。
しかし、変換が許可されていればどうなりますか?

+3

はい(もちろん、もちろん 'tmp'という名前は使用できません)。しかし、なぜあなたは気にしますか? –

+7

@BaummitAugen本当に? 'y'が他のスレッドからアクセスできる場合、変換は潜在的にデータ競合を招く可能性があります。 – hvd

+3

@hvd他のスレッドは 'x'や' y'にアクセスすることはできません。それは既にUBになるでしょう。明示するには:新しいレースはないか、コードは以前には壊れていたでしょう。 ( 'x'が' std :: atomic 'でない限り、Qはそれを言っていません) –

答えて

6

誤ったコメントに書いたのとは異なり、yが潜在的にスレッド間で共有され、コンパイラが元のコードで既存のUBを証明できない場合、この変換は実際には許可されません。

標準は、明示的に述べている:例えば 割り当て上書きかもしれないので 抽象機械によって修飾されないであろうことを潜在的に共有メモリロケーションへの割り当てを導入

コンパイラの変換は、一般的に、この標準によって排除されます抽象機械 の実行がデータ競合に遭遇しなかった場合の別のスレッドによる別の割り当て。

[intro.multithread](1.10/22)in N3337、N4141では(1.10/25)です。

したがって、xが常に0の場合、元のコードはレースフリーであり、変換されたコードはレースフリーではありません。したがって、変換は合法ではありません。

+0

簡単な質問では、この規格には「一般的に排除されている」と書かれていますが、それは違法ではない/存在しない理由が存在することを意味しますか?それともコンパイラが決定するのか? – user3164339

+1

@ user3164339この注釈は、「注:」*が残りの部分と同じように形式的ではない場合には、要約または重要な結論に近いものです。 * "一般的に排除された" *とは、 "特別な状況によって許可されない限り" *を意味する*。 –

+3

特に、他の誤ったコメントとは対照的に、as-ifルール自体には、単一のスレッドに対する制限がありません。データ競合をUBにすることにより、標準では、データ競合が発生せず、それに応じて最適化されるとオプティマイザが想定することができます。しかし、データレースを導入しない実装が導入されている場合、これはどこにもありません。 –

関連する問題

 関連する問題