title: In DCL Singleton without volatile, can NULL check be optimised out?
body: <p>A simple DCL singleton:</p>
  <pre><code>class Singleton {
   public:
    Singleton* GetInstance();
  
   private:
    Singleton() = default;
  
    static Singleton* s_instance;
    static std::mutex s_mutex;
  };
  
  Singleton* Singleton::GetInstance() {
    if (s_instance == nullptr) { // 1st check
      std::lock_guard&lt;std::mutex&gt; lock(s_mutex);
      if (s_instance == nullptr) { // 2nd (double) check
        s_instance = new Singleton();
      }
    }
    return s_instance;
  }
  </code></pre>
  <p>Here is my question:
  Papers like <a href="https://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf" rel="nofollow noreferrer">this</a> talk extensively about compiler optimisations can cause memory/ instruction reordering causing any of the thread to crash.</p>
  <p>But I didn't find any article talking about NULL check might getting optimised out if <code>s_instance</code> is not volatile. <strong>As no article talks about it, I need someone to verify if that's even possible.</strong></p>
  <p>I mean compiler converting the code to something like this:</p>
  <pre><code>class Singleton {
   public:
    Singleton* GetInstance();
  
   private:
    Singleton() = default;
  
    static Singleton* s_instance;
    static std::mutex s_mutex;
  };
  
  Singleton* Singleton::GetInstance() {
    if (s_instance == nullptr) { // 1st check
      std::lock_guard&lt;std::mutex&gt; lock(s_mutex);
      **// 2nd (double) check optimized out**
      s_instance = new Singleton();
    }
    return s_instance;
  }
  </code></pre>