Why is volatile needed in c?

来源:互联网 发布:网络连接超时怎么处理 编辑:程序博客网 时间:2024/05/29 10:14

Volatile tells the compiler not to optimize anything that has to do with the volatile variable.

There is only one reason to use it: When you interface with hardware.

Let's say you have a little piece of hardware that is mapped into RAM somewhere and that has two addresses: a command port and a data port:

typedef struct{  int command;  int data;  int isbusy;} MyHardwareGadget;

Now you want to send some command:

void SendCommand (MyHardwareGadget * gadget, int command, int data){  // wait while the gadget is busy:  while (gadget->isbusy)  {    // do nothing here.  }  // set data first:  gadget->data    = data;  // writing the command starts the action:  gadget->command = command;}

Looks easy, but it can fail because the compiler is free to change the order in which data and commands are written. This would cause our little gadget to issue commands with the previous data-value. Also take a look at the wait while busy loop. That one will be optimized out. The compiler will try to be clever, read the value of isbusy just once and then go into an infinite loop. That's not what you want.

The way to get around this is to declare the pointer gadget as volatile. This way the compiler is forced to do what you wrote. It can't remove the memory assignments, it can't cache variables in registers and it can't change the order of assignments either:

This is the correct version:

  
 void SendCommand (volatile MyHardwareGadget * gadget, int command, int data)    {      // wait while the gadget is busy:      while (gadget->isbusy)      {        // do nothing here.      }      // set data first:      gadget->data    = data;      // writing the command starts the action:      gadget->command = command;    }

43 down vote

Another use for volatile is signal handlers. If you have code like this:

quit = 0;while (!quit){    /* very small loop which is completely visible to the compiler */}

The compiler is allowed to notice the loop body does not touch the quit variable and convert the loop to a while (true) loop. Even if the quit variable is set on the signal handler for SIGINT and SIGTERM; the compiler has no way to know that.

However, if the quit variable is declared volatile, the compiler is forced to load it every time, because it can be modified elsewhere. This is exactly what you want in this situation.

 
18 down vote

volatile tells the compiler that your variable may be changed by other means, than the code that is accessing it. e.g., it may be a I/O-mapped memory location. If this is not specified in such cases, some variable accesses can be optimised, e.g., its contents can be held in a register, and the memory location not read back in again.

12 down vote

volatile in C actually came into existence for the purpose of not cacheing the values of the variable automatically. It will tell the machine not to cache the value of this variable. So it will take the value of the given volatile variable from the main memory every time it encounters it. This mechanism is used because at any time the value can be modified by the OS or any interrupt. So using volatile will help us accessing the value afresh every time.

3 down vote

There are two uses. These are specially used more often in embedded development.

  1. Compiler will not optimise the functions that uses variables that are defined with volatile keyword

  2. Volatile is used to access exact memory locations in RAM, ROM, etc... This is used more often to control memory-mapped devices, access CPU registers and locate specific memory locations.

See examples with assembly listing.Re: Usage of C "volatile" Keyword in Embedded Development

up vote 2 down vote

Volatile is also useful, when you want to force the compiler not to optimize a specific code sequence (e.g. for writing a micro-benchmark).

share|improve this answer
0 0