title: C++ Future Wrong Value in Release Version
body: <p>I've written a small thread pool class and adjusted it to the recommendations given by pschill (<a href="https://codereview.stackexchange.com/questions/229613/c-standard-thread-threadpool">https://codereview.stackexchange.com/questions/229613/c-standard-thread-threadpool</a>).
  I've now queuing several tasks until a thread can handle it.
  The task is made of a <code>enum class State</code>, <code>std::mutex</code>(for state) and a <code>std::packaged_task&lt;R(Args...)&gt;</code>. The task is created by the calling instance (see code example) and the lifetime is ensured and tested. As soon as a thread is ready the task is handled.
  Up to here everything works just fine in every build-configuration.</p>
  
  <p>The execution of a Debug x64 build (latest VCpp) gave me the expected value of <code>4</code>. Using any other configuration results in a "random" value....</p>
  
  <p>I've checked the lifetime of every object involved; just as expected.</p>
  
  <p><strong>Task execution</strong></p>
  
  <pre><code>{
      // May unnecessary but added due to previous errors
      std::lock_guard&lt;std::mutex&gt; 
      m_state = State::INPROGESS;
  }
  
  m_task(args...);
  
  {
      std::lock_guard&lt;std::mutex&gt; lock(m_statelock);
      m_state = State::DONE;
  }
  </code></pre>
  
  <p><strong>Queuing Task</strong></p>
  
  <pre><code>template &lt;typename R, typename ... Args&gt;
  void addTask(Task&lt;R, Args...&gt;&amp; task, Args ... args) {
      // m_tasks is a std::deque&lt;std::function&lt;void()&gt;&gt;
      std::lock_guard&lt;std::mutex&gt; lock(m_tasklock);
      m_tasks.emplace_back([&amp;]() -&gt; void {
          task.execute(args...);
      });
  
      // Has own mutex
      m_task_avaiable.notify_one(); // std::condition_variable
  }
  </code></pre>
  
  <p><strong>Thread Object Routine</strong></p>
  
  <pre><code>[&amp;]() -&gt; void {
      while (true) {
          while (tpool.m_tasks.size() &gt; 0) {
              {
                  // Added due to crash with Release-config at asgining
                  // atomic&lt;State&gt; in Task
                  std::lock_guard&lt;std::mutex&gt; lock(statelock);
                  state = State::INPROGRESS;
              }
  
              std::function&lt;void()&gt; job;
  
              {
                  std::lock_guard&lt;std::mutex&gt; lock(tpool.m_tasklock);
                  if (tpool.m_tasks.size() &gt; 0) {
                      job = std::move(tpool.m_tasks[0]);
                      tpool.m_tasks.pop_front();
                  }
              }
  
              if (job) { job(); }
      }
  
          {
              std::lock_guard&lt;std::mutex&gt; lock(statelock);
              state = State::IDLE;
          }
          tpool.m_task_avaiable.wait(lock);
          {
              std::lock_guard&lt;std::mutex&gt; lock(statelock);
              if (state == State::STOP) {
                  return; // To stop thread and make it joinable
              }
  
          }
      }
  }
  </code></pre>
  
  <p><strong>Main</strong></p>
  
  <pre><code>frm::util::ThreadPool pool(2);
  
  frm::util::Task&lt;int, int, int&gt; t1([](int a, int b) {
      std::this_thread::sleep_for(std::chrono::seconds(2));
      std::cout &lt;&lt; "Yey!...\n";
      return a + b;
  });
  
  
  pool.addTask(t1, 2, 2);
  
  // Direct access to member std::packaged_task&lt;...&gt; just for debugging
  std::cout &lt;&lt; t1.m_task.get_future().get() &lt;&lt; '\n';
  </code></pre>
  
  <p>If it helps, the dump of the task-object (x32) showing that a future was requested (byte 61):</p>
  
  <pre><code> class std::mutex   48 Byte
      1   0x02 0x00 0x00 0x00
      5   0xbc 0x78 0x9f 0x0f
      9   0x00 0x00 0x00 0x00
     13   0x00 0x00 0x00 0x00
     17   0x00 0x00 0x00 0x00
     21   0x00 0x00 0x00 0x00
     25   0x00 0x00 0x00 0x00
     29   0x00 0x00 0x00 0x00
     33   0x00 0x00 0x00 0x00
     37   0x00 0x00 0x00 0x00
     41   0xff 0xff 0xff 0xff
     45   0x00 0x00 0x00 0x00
   struct std::atomic&lt;enum frm::util::Task&lt;int,int,int&gt;::State&gt;    4 Byte
     49   0x02 0x00 0x00 0x00
   class std::packaged_task&lt;int __cdecl(int,int)&gt;   12 Byte
     53   0x50 0xbd 0x15 0x01
     57   0x00 0x00 0x00 0x00
     61   0x01 0x00 0x00 0x00
  </code></pre>
  
  <p>This there any problem with <code>std::future&lt;T&gt;</code>, <code>std::shared_future&lt;T&gt;</code> or <code>std::packaged_task&lt;T&gt;</code> in VCpp19 or do I miss something?</p>
  
  <p>I can show more code, but due to SO's rules and recommendations I've copied as few as possible.</p>
  
  <p>May also helps:</p>
  
  <p>Before using <code>addTask(Task&lt;R, Args...&gt;&amp; task, Args ... args)</code> <code>addTask(Task&lt;R, Args...&gt;* task, Args ... args)</code> resulted in an error (not in x64 debug) if there was a delay added like:</p>
  
  <pre><code>// Direct access to member std::packaged_task&lt;...&gt; just for debugging
  std::this_thread::sleep_for(std::chrono::seconds(2));
  std::cout &lt;&lt; t1.m_task.get_future().get() &lt;&lt; '\n';
  </code></pre>