Ben Braun
Ben Braun

Reputation: 428

Is 'volatile' sufficient to prevent C++ compilers from optimizing out a silent write?

I would like to write a function that triggers copy-on-write of a page, without having to modify any values in that page. A simple implementation:

void trigger_cow(char* addr){
    *addr = *addr;
}

doesn't work because GCC will optimize out the line. If I use volatile,

void trigger_cow(char* addr){
    volatile char* vaddr = (volatile char*) addr;
    *vaddr = *vaddr;
}

then this works under -O3.

Will this "hack" work under other compilers or optimization settings?

The description of volatile in most sites I've seen doesn't seem to describe what happens when you write to a volatile pointer, only what happens when you read from one. Thanks!

Upvotes: 5

Views: 2838

Answers (3)

Jerry Coffin
Jerry Coffin

Reputation: 490048

The standard (§1.9/8) requires that:

The least requirements on a conforming implementation are:
— Access to volatile objects are evaluated strictly according to the rules of the abstract machine.

"Access" is defined as either reading or writing, so yes, your *vaddr = *vaddr; must read a value from *vaddr, and then write the same value back to *vaddr.

Upvotes: 2

AnT stands with Russia
AnT stands with Russia

Reputation: 320371

Formally, any access to volatile variables constitutes observable behavior of the program. It cannot be optimized out and it cannot be reordered with regard to other elements of observable behavior.

Optimizations in C++ programs are carried out under that "as if" rule, which basically gives the compiler permission to do anything as long as it does not change the observable behavior of the program.

Upvotes: 3

Dietrich Epp
Dietrich Epp

Reputation: 213258

That is exactly what volatile does... it forces reads and writes to happen exactly once each time a variable is accessed, and in the same order as the reads and writes appear in the program (they cannot be reordered).

Note that the processor can still reorder reads and writes*, so volatile is not particularly useful for multithreaded programming.

*Except on the Itanium ABI, but that's unique.

Upvotes: 5

Related Questions