title: What causes the strange behaviors when calling a lambda with [&] capture clause inside which a variable outside current scope is used in C++?
body: <p>Consider the following code:</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;functional&gt;
  
  std::function&lt;void ()&gt; f()
  {
      int x = 666;
      return [&amp;] { std::cout &lt;&lt; x &lt;&lt; std::endl; };
  }
  
  int main()
  {
      f()();
      return 0;
  }
  </code></pre>
  <h2>Compiling with GCC 7.5.0 on Ubuntu 18.04 bionic (WSL):</h2>
  <h3>No optimization</h3>
  <pre><code>$ g++ -o main -std=c++14 -Wall main.cpp
  $ ./main
  666
  </code></pre>
  <h3><code>-O1</code></h3>
  <pre><code>$ g++ -o main -O1 -std=c++14 -Wall main.cpp
  $ ./main
  0
  </code></pre>
  <h3><code>-O2</code></h3>
  <pre><code>$ g++ -o main -O2 -std=c++14 -Wall main.cpp
  main.cpp: In function ‘int main()’:
  main.cpp:7:31: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]
       return [&amp;] { std::cout &lt;&lt; x &lt;&lt; std::endl; };
                                 ^
  $ ./main
  32699
  </code></pre>
  <h3><code>-O3</code></h3>
  <pre><code>$ g++ -o main -O3 -std=c++14 -Wall main.cpp
  main.cpp: In function ‘int main()’:
  main.cpp:7:31: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]
       return [&amp;] { std::cout &lt;&lt; x &lt;&lt; std::endl; };
                                 ^
  $ ./main
  32528
  </code></pre>
  <h2>Compiling with TDM-GCC 9.2.0 on Windows 10 x64:</h2>
  <h3>No optimization</h3>
  <pre><code>&gt;g++ -o main.exe -std=c++14 -Wall main.cpp
  
  &gt;.\main.exe
  666
  </code></pre>
  <h3><code>-O1</code></h3>
  <pre><code>&gt;g++ -o main.exe -O1 -std=c++14 -Wall main.cpp
  
  &gt;.\main.exe
  0
  </code></pre>
  <h3><code>-O2</code></h3>
  <pre><code>&gt;g++ -o main.exe -O2 -std=c++14 -Wall main.cpp
  
  &gt;.\main.exe
  0
  </code></pre>
  <h3><code>-O3</code></h3>
  <pre><code>&gt;g++ -o main.exe -O3 -std=c++14 -Wall main.cpp
  
  &gt;.\main.exe
  0
  </code></pre>
  <h2>Compiling with MSVC 19.27.29111 on Windows 10 x64:</h2>
  <h3>No optimization</h3>
  <pre><code>&gt;cl /EHsc main.cpp
  Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x86
  Copyright (C) Microsoft Corporation.  All rights reserved.
  
  main.cpp
  Microsoft (R) Incremental Linker Version 14.27.29111.0
  Copyright (C) Microsoft Corporation.  All rights reserved.
  
  /out:main.exe
  main.obj
  
  &gt;.\main.exe
  8402693
  </code></pre>
  <h3><code>/O1</code></h3>
  <pre><code>&gt;cl /EHsc /O1 main.cpp
  Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x86
  Copyright (C) Microsoft Corporation.  All rights reserved.
  
  main.cpp
  Microsoft (R) Incremental Linker Version 14.27.29111.0
  Copyright (C) Microsoft Corporation.  All rights reserved.
  
  /out:main.exe
  main.obj
  
  &gt;.\main.exe
  666
  </code></pre>
  <h3><code>/O2</code></h3>
  <pre><code>&gt;cl /EHsc /O2 main.cpp
  Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x86
  Copyright (C) Microsoft Corporation.  All rights reserved.
  
  main.cpp
  Microsoft (R) Incremental Linker Version 14.27.29111.0
  Copyright (C) Microsoft Corporation.  All rights reserved.
  
  /out:main.exe
  main.obj
  
  &gt;.\main.exe
  666
  </code></pre>
  <p>As you can see, with different compilers and optimization levels, the program outputs <code>666</code>, <code>0</code>, or a garbage value. Why does the above happen?</p>