18

What is the purpose of volatile keyword in C#?

Where would I need to use this keyword?

I saw the following statement, but I am unable to understand why volatile is required here?

internal volatile string UserName; 
Adi Lester
  • 24,731
  • 12
  • 95
  • 110
Zain Shaikh
  • 6,013
  • 6
  • 41
  • 66

6 Answers6

30

I refer you to section 10.5.3 of the specification, which states:

For non-volatile fields, optimization techniques that reorder instructions can lead to unexpected and unpredictable results in multi-threaded programs that access fields without synchronization such as that provided by the lock-statement (§8.12). These optimizations can be performed by the compiler, by the run-time system, or by hardware. For volatile fields, such reordering optimizations are restricted:

A read of a volatile field is called a volatile read. A volatile read has “acquire semantics”; that is, it is guaranteed to occur prior to any references to memory that occur after it in the instruction sequence.

A write of a volatile field is called a volatile write. A volatile write has “release semantics”; that is, it is guaranteed to happen after any memory references prior to the write instruction in the instruction sequence.

These restrictions ensure that all threads will observe volatile writes performed by any other thread in the order in which they were performed. A conforming implementation is not required to provide a single total ordering of volatile writes as seen from all threads of execution.

Read that extremely carefully if you have any intention of ever making a volatile field. If you do not completely and thoroughly understand all the implications of volatile semantics then do not attempt to use them. It is usually far better to use a lock, which automatically gives you sufficient memory barriers to ensure the necessary acquire and release semantics. Remember, locks are only really expensive when they are contended.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
7

Volatile is used for a variable that can change without your action while your code is running. It tells the compiler to write the assembly in such a way as to not ever cache the variable, but to instead be sure to read it before every use.

An example of something that would be volatile would be a hardware register that your code has memory mapped and is reading to determine when a flag is set. The hardware may set the value while your code is running and without using the volatile keyword you would not notice this change as the assembly would not ever actually check the value.

w.donahue
  • 10,790
  • 13
  • 56
  • 78
6

Volatile is a hint for the compiler (and ngen/jit compiler) that the value of this variable can change at any moment, and thus optimizations around accessing the variable by caching the value locally volatile be disabled.

Consider the following code:

If (UserName == "")
    // do something
If (UserName == "Fred")
    // do something

If volatile was not present, the compiler might generate IL where it stores the reference on the stack for the first comparison and than reuses it for the second one. However, adding volatile tells the compiler that the reference might be changed by another thread, thus forcing it to generate IL that will not reuse the stack copy from the first comparison.

Franci Penov
  • 74,861
  • 18
  • 132
  • 169
  • hmm, you mean, each time variable is accessed it will generate new IL instead of using the stack copy, right? – Zain Shaikh Nov 05 '10 at 03:57
  • Yes, if volatile is present, the compiler will generate new IL instructions to get the field value for each field access. If volatile is not present, the compelled might skip that IL for the second and subsequent filled access. – Franci Penov Nov 05 '10 at 04:00
  • It's worth noting that this is only necessary with multi-threaded applications. One thread might read UserName, then the CPU switches to the other thread, it updates UserName, then the CPU switches back. the first thread now has an old version of UserName unless it rechecks it. – jb. Nov 05 '10 at 05:34
4

MSDN will summarize better than I....

"The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread. This ensures that the most up-to-date value is present in the field at all times."

http://msdn.microsoft.com/en-us/library/x13ttww7(v=VS.100).aspx

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Chris Baxter
  • 16,083
  • 9
  • 51
  • 72
3

It indicates that the value may get changed by a different thread, so the value needs to be read even if a previous instruction has already read it.

http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.71%29.aspx

heisenberg
  • 9,665
  • 1
  • 30
  • 38
2

It is nothing but telling to compiler that this variable will change its value at anytime by means of anything and compiler should not make any assumption about this variable.

Normally compiler will assume that some variable will be constant during runtime. This may lead error in checking a registor value repeatedly. Because the register value may be changed by anything. So for these kind of variables should be declared 'volatile' and it be checked each time appears in the code with out any assumption.

Singleton
  • 3,701
  • 3
  • 24
  • 37