Search code examples
c#language-lawyercompiler-optimizationvolatilelock-free

Does volatile prevent introduced reads or writes?


In C#, volatile keyword ensures that reads and writes have acquire and release semantics, respectively. However, does it say anything about introduced reads or writes?

For instance:

volatile Thing something;
volatile int aNumber;

void Method()
{
    // Are these lines...
    var local = something;
    if (local != null)
        local.DoThings();

    // ...guaranteed not to be transformed into these by compiler, jitter or processor?
    if (something != null)
        something.DoThings(); // <-- Second read!



    // Are these lines...
    if (aNumber == 0)
        aNumber = 1;

    // ...guaranteed not to be transformed into these by compiler, jitter or processor?
    var temp = aNumber;
    if (temp == 0)
        temp = 1;
    aNumber = temp; // <-- An out-of-thin-air write!
}

Solution

  • Here's what the C# spec1 has to say about Execution Order:

    Execution of a C# program proceeds such that the side effects of each executing thread are preserved at critical execution points. A side effect is defined as a read or write of a volatile field ...

    The execution environment is free to change the order of execution of a C# program, subject to the following constraints:

    ...

    The ordering of side effects is preserved with respect to volatile reads and writes ...

    I would certainly consider introducing new side effects to be changing the order of side effects, but it's not explicitly stated like that here.


    Link in answer is to the C# 6 spec which is listed as Draft. C# 5 spec isn't a draft but is not available on-line, only as a download. Identical wording, so far as I can see in this section.