6

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?

Coding Mash
  • 3,338
  • 5
  • 24
  • 45
Whoami
  • 13,930
  • 19
  • 84
  • 140
  • Here is some background on sequence points - http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html – Justin Ethier Nov 02 '12 at 14:32
  • 2
    It means that during the optimization and instruction generation passes, when code/instructions can otherwise be reordered, interleaved, etc. for more efficient execution, the instructions that access volatile variables are considerably more restricted in how they can be affected. – twalberg Nov 02 '12 at 14:41

4 Answers4

4

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.

Lundin
  • 195,001
  • 40
  • 254
  • 396
2

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.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Or rather, reading or writing to a volatile variable is a side-effect, and the compiler may not move side-effects across sequence points. The text you "cite" is not from any C standard. – Lundin Nov 02 '12 at 15:13
1

In the context of the C++ "abstract machine", a program is defined by the sequence of volatile accesses performed ("observable behaviour"), anything else may be changed by the optimizer.

For example, if you have a CPU with many registers, it is completely acceptable for the compiler to store objects in them, unless they are declared volatile. Someone looking at the memory accesses performed by the CPU would no longer see everything the program does, but is guaranteed the volatile accesses will be there.

The program is optimized correctly if it produces the same sequence of volatile accesses with the same data as an unoptimized program.

The concept of sequence points lives on another layer -- this concerns the ordering of operations inside the abstract machine. If you have two operations with no sequence point in between, there are no ordering guarantees, which is why x = 0; return x++ + x++; does not have a defined result.

Putting these two concepts together is difficult, because so very little is guaranteed about non-volatile accesses. The only example I could think of quickly would be

int *y = ...;
volatile int *x = ...;
std::exception up;

if (*y == 0)
    throw up;

return *x;

As *y is not volatile, it is perfectly acceptable to move any accesses to it anywhere and even optimize them out if possible, but in no case may *x be evaluated if *y == 0.

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
0

Volatile means that your variable may be modified outside your program and that the compiler cannot optimize its access, by moving it in expression sequences (instructions) of your program. A good example of volatile usage is the OS ticks. volatile is a hint for the optimizer to say that we do not want him to change its access : in the example of os ticks, we do not want to read it later or sooner than where it is coded.

ARA
  • 1,296
  • 10
  • 18