1

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?
  • 3
    It could be a register of a microcontroller connected to an input pin – Thomas Sablik Jan 19 '20 at 15:08
  • 2
    Registers changed by hardware. Variables changed by kernel interrupt routines – stark Jan 19 '20 at 15:09
  • 2
    `volatile` is designed for memory-mapped hardware registers. In such an implementation, reading a particular memory address obtains a value from external device, and writing to it sends data to external device. The value read from such an address may change spontaneously, without being assigned to. – Igor Tandetnik Jan 19 '20 at 15:09

1 Answers1

4

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.

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78
  • 2
    _"...This makes volatile objects suitable for communication with a signal handler, but not with another thread of execution..."_ https://en.cppreference.com/w/cpp/language/cv Use `std::atomic` not `volatile` when using threads. – Richard Critten Jan 19 '20 at 15:24
  • @RichardCritten this clause is incorrect. If something modifies your function without your knowledge, this may as well be in another thread. – Michael Chourdakis Jan 19 '20 at 15:26
  • @MichaelChourdakis http://isvolatileusefulwiththreads.in/C++/ – Cubbi Jan 23 '20 at 14:53
  • @MichaelChourdakis: For execution contexts that use the same view of cache as the main thread, suitability for the purpose is Implementation Defined. MSVC traditionally treated "volatile" in a high-quality fashion that was sufficient for many tasks in cases where hardware caching wouldn't pose an issue. Some other compilers take the attitude that the Standard's failure to mandate that compilers do so even on platforms where doing so would be useless represents a judgment that compilers shouldn't be configurable to do so. – supercat Mar 09 '20 at 03:27