Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the order of writes to separate members of a volatile struct guaranteed to be preserved?

Suppose I have a struct like this:

volatile struct { int foo; int bar; } data; data.foo = 1; data.bar = 2; data.foo = 3; data.bar = 4; 

Are the assignments all guaranteed not to be reordered?

For example without volatile, the compiler would clearly be allowed to optimize it as two instructions in a different order like this:

data.bar = 4; data.foo = 3; 

But with volatile, is the compiler required not to do something like this?

data.foo = 1; data.foo = 3; data.bar = 2; data.bar = 4; 

(Treating the members as separate unrelated volatile entities - and doing a reordering that I can imagine it might try to improve locality of reference in case foo and bar are at a page boundary - for example.)

Also, is the answer consistent for current versions of both C and C++ standards?

like image 956
Ted Shaneyfelt Avatar asked Dec 14 '20 20:12

Ted Shaneyfelt


People also ask

Can volatile be reordered?

The answer to the general question of whether a volatile read can be re-ordered is yes, yes it can. Though a volatile read in a loop cannot be cached once and elided, a volatile read can be moved backwards in time with respect to a volatile write.

What does volatile keyword do in C++?

Volatile Keyword in C/C++ Volatile is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change any time.


1 Answers

c

They will not be reordered.

C17 6.5.2.3(3) says:

A postfix expression followed by the . operator and an identifier designates a member of a structure or union object. The value is that of the named member, 97) and is an lvalue if the first expression is an lvalue. If the first expression has qualified type, the result has the so-qualified version of the type of the designated member.

Since data has volatile-qualified type, so do data.bar and data.foo. Thus you are performing two assignments to volatile int objects. And by 6.7.3 footnote 136,

Actions on objects so declared [as volatile] shall not be “optimized out” by an implementation or reordered except as permitted by the rules for evaluating expressions.

A more subtle question is whether the compiler could assign them both with a single instruction, e.g., if they are contiguous 32-bit values, could it use a 64-bit store to set both? I would think not, and at least GCC and Clang don't attempt to.

like image 140
Nate Eldredge Avatar answered Sep 18 '22 13:09

Nate Eldredge