Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You're probably familiar with <code>const</code> methods and const-correctness (cf. "Item 15 - Use const proactively" in <em><a href="http://rads.stackoverflow.com/amzn/click/0321113586" rel="nofollow noreferrer">C++ Coding Standards</a></em> by Sutter and Alexandrescu), and <code>volatile</code> works in similar but slightly different ways to yield what might be called "volatile-correctness." </p> <p>Like <code>const</code>, <code>volatile</code> is a type modifier. When attached to a member function as in your example, either modifier (or both!) mean that the object on which the method is called must have or be convertible to that type.</p> <p>Consider:</p> <pre><code>struct A { void f(); void cf() const; void vf() volatile; void cvf() const volatile; // ... }; void foo( A&amp; a, const A&amp; ca, volatile A&amp; va, const volatile A&amp; cva ) { a.f(); // Ok a.cf(); // Ok: Can convert non-const obj to const obj a.vf(); // Ok: Can convert non-volatile obj to volatile obj a.cvf(); // Ok: Can convert non-cv obj to cv obj ca.f(); // Error: can't call non-const method on const obj ca.cf(); // Ok ca.vf(); // Error: can't call non-const method on const obj ca.cvf(); // Ok: Can convert va.f(); // Error: can't call non-volatile method on volatile obj va.cf(); // Error: can't call non-volatile method on volatile obj va.vf(); // Ok va.cvf(); // Ok: Can convert cva.f(); // Error: can't call non-cv method on cv obj cva.cf(); // Error: can't call non-cv method on cv obj cva.vf(); // Error: can't call non-cv method on cv obj cva.cvf(); // Ok } </code></pre> <p>Note these are compile-time errors, not run-time errors, and that is where it's potential usefulness comes in. </p> <p>Const-correctness prevents unintentional errors <em>at compile-time</em> as well as making code "easier to understand, track, and reason about" (Sutter and Alexandrescu). Volatile-correctness can function similarly but is much less used (note that <code>const_cast</code> in C++ can cast away <code>const</code>, <code>volatile</code>, or <code>const volatile</code>, but rather than calling it <code>cv_cast</code> or similar, it's named after <code>const</code> alone because it is far more commonly used for casting away just <code>const</code>).</p> <p>For instance, in <a href="http://www.drdobbs.com/184403766;jsessionid=NIOMCX3NKZF0ZQE1GHPCKH4ATMY32JVN" rel="nofollow noreferrer">"volatile - Multithreaded Programmer's Best Friend"</a>, Andrei Alexandrescu gives some examples of how this can be used to have the compiler automatically detect race conditions in multithreaded code. It has plenty of explanation about how type modifiers work, too, but see also his follow-up comments in his <a href="http://www.drdobbs.com/184403774;jsessionid=RWBZ1W2RDBPBLQE1GHPCKH4ATMY32JVN" rel="nofollow noreferrer">subsequent column</a>.</p> <hr> <p><em>Update</em>:</p> <p>Note that C++11 changes the meaning of <code>const</code>. <a href="https://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/" rel="nofollow noreferrer">Thus sayeth the Sutter</a>: "<code>const</code> now really does mean 'read-only, or safe to read concurrently'—either truly physically/bitwise <code>const</code>, or internally synchronized so that any actual writes are synchronized with any possible concurrent <code>const</code> accesses so the callers can’t tell the difference."</p> <p>Elsewhere, <a href="https://herbsutter.com/2014/01/13/gotw-95-solution-thread-safety-and-synchronization/" rel="nofollow noreferrer">he notes</a> that while C++11 has added concurrency primitives, <code>volatile</code> is still not one of them: "C++ volatile variables (which have no analog in languages like C# and Java) are always beyond the scope of this and any other article about the memory model and synchronization. That’s because C++ volatile variables aren’t about threads or communication at all and don’t interact with those things. Rather, a C++ volatile variable should be viewed as portal into a different universe beyond the language — a memory location that by definition does not obey the language’s memory model because that memory location is accessed by hardware (e.g., written to by a daughter card), have more than one address, or is otherwise 'strange' and beyond the language. So C++ volatile variables are universally an exception to every guideline about synchronization because are always inherently “racy” and unsynchronizable using the normal tools (mutexes, atomics, etc.) and more generally exist outside all normal of the language and compiler including that they generally cannot be optimized by the compiler.... For more discussion, see my article '<a href="http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484" rel="nofollow noreferrer">volatile vs. volatile</a>.'"</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload