Search code examples
c++cobjectmemoryvolatile

What are "undetectable means" and how can they change objects of a C/C++ program?


In ISO/IEC 14882:2003 (C++03) is stated under 7.1.5.1/8, section "The cv-qualifers":

[Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are in C. ]


These "means", that are undetectable by an implementation has been also already subject of Nawaz´ Q&A Why do we use volatile keyword:

However, sometimes, optimization (of some parts of your program) may be undesirable, because it may be that someone else is changing the value of some_int from outside the program which compiler is not aware of, since it can't see it; but it's how you've designed it. In that case, compiler's optimization would not produce the desired result!

But unfortunately, he missed to explain what these "means", that may change objects from outside the program, can be and how they can change objects.


My Question:

  • What are examples for these "undetectable means" and how are they be able to change internal objects of a program from outside of it?

Solution

  • A pointer in memory may be visible by other parts of the same or another program. For example, a variable that exists in shared memory and can be changed by another program.

    The compiler cannot detect that.

    Other examples are hardware-based memory locations.

    Generally, apps that need volatile variables usually deal with stuff like asynchronous audio, and at the system level, interrupts, APIC etc. Most apps do not need them.

    An imaginary example:

    int v = 0;
    
    // Some thread
    SetUpdatesOn(&v);
    
     // Another thread
    for(;;)
    {
       int g = v;
       std::cout << g;
    }
    

    Assume that an imaginary OS-level function SetUpdatesOn periodically changes the variable passed to it. If the variable is not declared volatile, the compiler might optimize the int g = v call or assume that v always has the same value.

    If the variable is declared volatile, the compiler will keep reading it in the loop.

    Note that very often it is difficult to debug such programming mistakes because the optimization may only exist in release builds.