Consider the following code:
#include <iostream>
#include <functional>
std::function<void ()> f()
{
int x = 666;
return [&] { std::cout << x << std::endl; };
}
int main()
{
f()();
return 0;
}
Compiling with GCC 7.5.0 on Ubuntu 18.04 bionic (WSL):
No optimization
$ g++ -o main -std=c++14 -Wall main.cpp
$ ./main
666
-O1
$ g++ -o main -O1 -std=c++14 -Wall main.cpp
$ ./main
0
-O2
$ 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 [&] { std::cout << x << std::endl; };
^
$ ./main
32699
-O3
$ 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 [&] { std::cout << x << std::endl; };
^
$ ./main
32528
Compiling with TDM-GCC 9.2.0 on Windows 10 x64:
No optimization
>g++ -o main.exe -std=c++14 -Wall main.cpp
>.\main.exe
666
-O1
>g++ -o main.exe -O1 -std=c++14 -Wall main.cpp
>.\main.exe
0
-O2
>g++ -o main.exe -O2 -std=c++14 -Wall main.cpp
>.\main.exe
0
-O3
>g++ -o main.exe -O3 -std=c++14 -Wall main.cpp
>.\main.exe
0
Compiling with MSVC 19.27.29111 on Windows 10 x64:
No optimization
>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
>.\main.exe
8402693
/O1
>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
>.\main.exe
666
/O2
>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
>.\main.exe
666
As you can see, with different compilers and optimization levels, the program outputs 666
, 0
, or a garbage value. Why does the above happen?