2016-05-20 2 views
3

私はC++のクイズサイトで以下のコードを調べました。それはまた説明を提供する。私はvolatile修飾子が変数の値が他のいくつかの要因によって変更される可能性があることをコンパイラに知らせることを認識しています。このサイトの説明によると、volatileにアクセスするには順序を付けるべきだという。なぜ、どのように配列を決定すべきですか?C++:なぜ揮発性アクセスはシーケンシングを必要としますか?

の意味がわからないおよびスカラーオブジェクト。また、それを明確にしてください。ここ

#include <iostream> 
volatile int a; 
int main() { 
    std::cout << (a + a); 
} 

問題は、変数aの不足している初期化子ではありません - それ が暗黙のうちにここに0に初期化されます。しかし、問題は、アクセス間のシーケンシングなしに、2回のアクセス へのアクセスです。 §1.9¶12によると、volatile glvaluesのアクセスは副作用であり、 〜§1.9¶15によると、同じスカラー オブジェクト上のこれらの2つの順序付けられていない副作用は、未定義の動作になります。

答えて

5

2つのアクセスのどちらが最初に発生するかはここでは定義されていません。

この対称加算演算の場合は関係ありません。

しかし、対称ではない別の操作を考慮しては:

std::cout << a * (a+1); 

、外部要因による、自動的にすべてのアクセス後にインクリメントされます、volatileオブジェクトを検討します。例えば、aが何らかの種類のハードウェアレジスタであるとします。私が言ったように、アクセスされるたびに増分されるので、ハードウェアレジスタには最初のアクセスでは4、2番目のアクセスでは5が含まれているとします。簡単なカウンター。

最初のアクセスは、乗算の左側のためであり、第二のアクセスは、乗算の右側アクセスに加えて動作のためであった場合、これは

std::cout << 4 * (5+1); 

しかし場合なりますこれはvolatileオブジェクトを持つことは十分ではありません理由です

std::cout << 5 * (4+1); 

となり、最初のアクセスは、右側のためだった、と第二のアクセスは、左側のためでした。操作を順序付けする必要があります。

+1

しかし、実際には未定義の動作になるか、または単に指定されていないのでしょうか? –

+1

@ MarkB、それはUBです:スカラーオブジェクトの**副作用**が同じスカラーオブジェクトの別の副作用または同じスカラーオブジェクトの値を使った値計算と比較して順序付けされていない潜在的に同時に(1.10)、その動作は未定義です。_そして、揮発性のオブジェクトにアクセスすることは副作用です – ixSci

+0

@SamVarshavchik、私はあなたの結論が少し誤解を招くと言います。この特定の問題は 'a'オブジェクトの「揮発性」性質のために存在します。あなたがコースに並行してアクセスしていなければ、それは「揮発性」でなく、問題はなくなります。もしあなたがいれば競争状態があり、そのような場合には「揮発性」は利点がありません。 – ixSci

関連する問題