31

I read some tutorial about volatile in the C language, but I still can not figure it out. Some say the volatile tells the complier optimizer that operations involving this variable should not be optimized in certain ways. This means anytime the value of a variable is changed in a register, then the value should affect the memory.

And also some say that volatile mean that the value can be changed by means outside this code.

I can not understand the second saying. So the volatile variable can be changed by means outside of this code? How? And are these two statements both right?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131

6 Answers6

43

The statement "the value can be changed by means outside of this code" basically means that another program or hardware can update that variable. This is totally possible. One way of thinking of this is by relating this concept to a file that is shared among multiple programs. A file can be opened, written, and read by many programs at once. When you read from a file you want to make sure that you are reading the latest update and not the oldest.

Going back to the volatile keyword, placing volatile before a variable, in effect, does the same thing. It makes sure that what you are reading out of the variable isn't based on the compiler's optimization or an old copy of the variable that your program had. Moreover, the volatile keyword ensures that the variable is fetched from memory on every access. Therefore, both of those statements are correct regarding the volatile keyword.

WindsurferOak
  • 4,861
  • 1
  • 31
  • 36
  • 1
    I do not understand how a hardware change the variable? does that mean hardware do not need some method or code to modify the variable? –  Apr 28 '11 at 17:30
  • 9
    @ratzip: Yes. A variable is a location in memory which contains a value, and memory is a just a piece of hardware (a RAM chip, for example). Many computer systems (keyboard, network, audio input, etc.) are set up so that external hardware can modify certain memory locations directly. – e.James Apr 28 '11 at 17:40
21

C isn't necessarily for computers. For example, if you're developing for the Game Boy Advance, you often come upon memory locations that are modified by the hardware, so you might not modify the variable in your code, but it gets modified anyway. That's what volatile means.

By adding the volatile keyword, you're telling the compiler that "The value stored in this variable (memory location) might change without my code doing anything."

aviraldg
  • 9,531
  • 6
  • 41
  • 56
  • Why is this part of the C standard instead of an extension for those implementations - there's no conforming way to get an address that points to memory that behaves in such a way. – Random832 Apr 28 '11 at 17:12
  • 2
    @Random: Because that's how it is. Anyway, almost every single platform ever will need to interact with hardware at some point. – Oliver Charlesworth Apr 28 '11 at 17:14
  • On certain embedded platforms - Like the GBA, you have memory-mapped registers, so you know for a fact that a certain region in memory *will* behave that way. – aviraldg Apr 28 '11 at 17:15
  • @Random: Can you explain this? You don't think it's possible to instruct attached devices to use particular memory locations as their buffers or where to transmit received signals? – Andrew Lazarus Apr 28 '11 at 17:16
  • @Random: That is simply not correct. A multithreaded application can *easily* produce code in which two threads access the same memory location asynchronously. – e.James Apr 28 '11 at 17:26
  • @Andrew Lazarus it's not possible in a portable C program - the standard doesn't define any way to do so. @e.James And the C standard doesn't provide multithreading, so why should it provide keywords that are only necessary/useful if extensions are used? – Random832 Apr 28 '11 at 17:28
  • @Random832: Because the machines used around when the C Standard was developed needed it? (and UNIX needed it.) – aviraldg Apr 28 '11 at 17:30
  • 5
    @Random: The C standard doesn't define how `#include`s should be resolved, either. That doesn't mean that they're not useful. – Oliver Charlesworth Apr 28 '11 at 17:32
15

Consider any of the following:

  • a multi-threaded application,
  • an application using shared memory,
  • an application running on a platform that maps I/O registers into the address space,
  • an application with hardware DMA occurring in the background.

In each of these situations, memory can be altered outside the current thread.

Note that "anytime the value of a variable is change in register, then the value should affect the memory" is correct, just not very clear.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • and also the both sayings are right? –  Apr 28 '11 at 17:19
  • 3
    but `volatile` is very, very rarely useful for multi-thread code. – curiousguy Oct 26 '11 at 22:53
  • 2
    volatile is also useful in the case of data that could be modified by an asynchronous event, such as the execution of signal handler code (i.e. the signal handler code modified the variable). – vyudh Apr 09 '13 at 02:35
  • 4
    There is no requirement in the C specification that volatile have acquire/release semantics or any other semantics that are actually useful for multithreaded code. Remember, different threads may be operating against inconsistent caches on different processors; there is no requirement that a compiler implement volatile to take that into account. Unless you are writing code for a specific compiler and you know what extensions to the C language the compiler implements with respect to volatile, you should not use volatile for threading semantics. – Eric Lippert Jun 10 '14 at 16:42
  • @EricLippert: There is also no requirement in the C Standard that a conforming implementation be suitable for any purpose whatsoever. The fact that the Standard does not require that a conforming implementation do something does not in any way imply that quality implementations intended to be suitable for low-level programming shouldn't. Unfortunately, it's fashionable for compilers to treat quality-of-implementation issues as an excuse to implement poor-quality semantics. – supercat Jul 13 '18 at 22:33
6

A memory location can be changed outside a programs code in a huge number of ways. For example, a DMA read from a disk can write into a buffer, or a memory mapped device can change a location because of some event on the device.

3

This addresses, for example, multi-threaded applications: The value of a variable can be changed by several threads and thus has to be "synchronized" with the memory on each access (regardless of whether reading or writing the value).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Flinsch
  • 4,296
  • 1
  • 20
  • 29
2

Declaring a volatile variable means, you are instructing compiler not to optimize the code snippet around that variable. This is to force the CPU to not to use the variable value from local registers or cache memory, but to fetch the value from main memory every time.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131