Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A compiler may not move accesses to volatile variables across sequence points; what does it mean?

Declaring a variable as 'volatile' means to read/write directly from the memory location, not from the register variable. I have a knowledge about 'sequence point'. But i dont understand the statement mentioned in the title.

Could someone explain the same, and give some code snippet also?

like image 370
Whoami Avatar asked Nov 02 '12 14:11

Whoami


2 Answers

All of this is described in C11 5.1.2.3

Program execution

/--/

Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment. Evaluation of an expression in general includes both value computations and initiation of side effects.

Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread, which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. ...

The presence of a sequence point between the evaluation of expressions A and B implies that every value computation and side effect associated with A is sequenced before every value computation and side effect associated with B.

/--/

An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

/--/

The least requirements on a conforming implementation are:

— Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.

This isn't exactly easy to interpret, but what it roughly means in plain English is: since the access of volatile objects is a side effect, the compiler is not allowed to optimize away such accesses, neither is it allowed to sequence them in a different order, which it would otherwise perhaps do in order to get better performance on a CPU with instruction cache/branch prediction, or just better performance because it had certain values conveniently stored in some CPU register.

(The C11 standard also explicitly states that volatile objects aren't guaranteed to be thread-safe, the value of a volatile object after a context switch is unspecified behavior.)

EDIT an example

Given the code

volatile int x;
volatile int y;
volatile int z;

x=i;
y=something;
z=i;

then the compiler is not allowed to re-order the instructions in the executable to

x=i;
z=i;
y=something

because the access to y must be sequenced before the access to z. There is a sequence point at the semi colon. But if the variables had not been volatile, it would be fine for the compiler to re-order them, if it could determine that it would not affect the outcome of the program.

like image 117
Lundin Avatar answered Sep 20 '22 16:09

Lundin


Consider this deliberately contrived example:

volatile int v = 5;
int x;
int y = (x=7), (x+v);

Recall that comma creates a sequence point. Therefore, the assignment x=7 will be completed before x+v is evaluated. Moreover, since v is volatile, the compiler may not assume that it's 5 simply because there is no code modifying v between its declaration and the point of access: the compiler must generate an instruction to read v.

However, this leaves an important decision up to the compiler: when exactly should v be read? More specifically, would it be OK to read v before assigning x?

This is where the statement from your question comes in:

A compiler may not move accesses to volatile variables across sequence points

It explicitly prohibits the compiler from reading v before assigning x, because doing so would move the access across the sequence point created by the comma operator. Without this restriction, the compiler would have been free to read v either before or after assigning x.

like image 33
Sergey Kalinichenko Avatar answered Sep 22 '22 16:09

Sergey Kalinichenko