C# compiler optimization and volatile keyword

.net, c#, multithreading, volatile

Solution

So, as far as I understand, the following should never exit.

No, it can stop. It just isn't guaranteed to.

It doesn't stop on the machine I'm currently running on, for example - but equally I could try the exact same executable on another machine and it might behave fine. It will depend on the exact memory model semantics used by the CLR it runs on. That will be affected by the underlying architecture and potentially even the exact CPU being used.

It's important to note that it's not the C# compiler which determines what to do with a `volatile` field - the C# compiler just indicates the volatility in the metadata using `System.Runtime.CompilerServices.IsVolatile`. Then the JIT can work out what that means in terms of obeying the relevant contracts.

Problem

I have read some posts about `volatile` keyword and behaviour without this keyword. I've especially tested the code from the answer to Illustrating usage of the volatile keyword in C#. When running, I observe the excepted behaviour in Release mode, without debugger attached. Up to that point, there is no problem. So, as far as I understand, the following code should never exit. ``` public class Program { private bool stopThread; public void Test() { while (!stopThread) { } // Read stopThread which is not marked as volatile Console.WriteLine("Stopped."); } private static void Main() { Program program = new Program(); Thread thread = new Thread(program.Test); thread.Start(); Console.WriteLine("Press a key to stop the thread."); Console.ReadKey(); Console.WriteLine("Waiting for thread."); program.stopThread = true; thread.Join(); // Waits for the thread to stop. } } ``` Why does it exit? Even in Release mode, without debugger? Update An adaptation of the code from Illustrating usage of the volatile keyword in C#. ``` private bool exit; public void Test() { Thread.Sleep(500); exit = true; Console.WriteLine("Exit requested."); } private static void Main() { Program program = new Program(); // Starts the thread Thread thread = new Thread(program.Test); thread.Start(); Console.WriteLine("Waiting for thread."); while (!program.exit) { } } ``` This program does not exit after in Release mode, without debugger attached.

Original source

Related problems