73
votes

From what I've read from Herb Sutter and others you would think that volatile and concurrent programming were completely orthogonal concepts, at least as far as C/C++ are concerned.

However, in GCC implementation all of std::atomic's member functions have the volatile qualifier. The same is true in Anthony Williams's implementation of std::atomic.

So what's deal, do my atomic<> variables need be volatile or not?

3
+1 Mr. Williams is here on SO, maybe he can show up and give an answer :)AraK
I've seen a question on comp.std.c++ about that. Remember that volatile guarants that reads and writes in a single thread are done in order and that a volatile object cannot have any non-volatile member functions being called on it (just like const). But further than that, i have no clue about threads in C++. Everytime i try to read about it in the Standard, i'm starting to give up, not being able to grasp the sheer amount of indirections and logics in the text xDJohannes Schaub - litb

3 Answers

80
votes

To summarize what others have correctly written:

C/C++ volatile is for hardware access and interrupts. C++11 atomic<> is for inter-thread communication (e.g., in lock-free code). Those two concepts/uses are orthogonal, but they have overlapping requirements and that is why people have often confused the two.

The reason that atomic<> has volatile-qualified functions is the same reason it has const-qualified functions, because it's possible in principle for an object be both atomic<> and also const and/or volatile.

Of course, as my article pointed out, a further source of confusion is that C/C++ volatile isn't the same as C#/Java volatile (the latter is basically equivalent to C++11 atomic<>).

58
votes

Why is the volatile qualifier used throughout std::atomic?

So that volatile objects can also be atomic. See here:

The relevant quote is

The functions and operations are defined to work with volatile objects, so that variables that should be volatile can also be atomic. The volatile qualifier, however, is not required for atomicity.

Do my atomic<> variables need to be volatile or not?

No, atomic objects don't have to be volatile.

15
votes

As const, volatile is transitive. If you declare a method as volatile then you cannot call any non-volatile method on it or any of its member attributes. By having std::atomic methods volatile you allow calls from volatile member methods in classes that contain the std::atomic variables.

I am not having a good day... so confusing... maybe a little example helps:

struct element {
   void op1() volatile;
   void op2();
};
struct container {
   void foo() volatile {
      e.op1();  // correct
      //e.op2();  // compile time error
   }
   element e;
};