I've been working on some win32 wrappers (for self-exercise / hobby so it is not as clean as it should be). I've encounter an interesting bug?/feature that automatically returns variables without an explicit return and I'd like more insight on why this is occurring.
I have a strong feeling this is either me exploiting undefined behavior or is a bug because it is not always reproducible.
Consider this:
int foo() {
int i;
i = 2;
if (false)
throw "";
}
int x = foo();
This compiles with MSVC++2015 and it returns 0. Strangely however my custom Windows class actually returns a correct result:
struct Window {
static HWND makeWnd(const TCHAR* title) {
static struct init {
init() {
WNDCLASSEX wc = {};
wc.lpszClassName = "windowClass";
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = DefWindowProc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbWndExtra = sizeof(Window*);
if (RegisterClassEx(&wc) == 0)
throw "Failed to Register";
}
} _;
// B) _hwnd created here, NOT class hwnd
HWND _hwnd = 0;
if (!(_hwnd = CreateWindowEx(0, "windowClass", title, WS_OVERLAPPED,
0, 0, 640, 480, 0, 0, GetModuleHandle(NULL), 0)))
throw "Failed to create hwnd";
// C) No return on _hwnd here!
}
HWND hwnd;
// A) Constructor calls makeWnd, hwnd initially 0xcccc...
Window(const TCHAR* title)
: hwnd(makeWnd(title)) {
// D) hwnd is now the value _hwnd had
}
};
When running:
Window window("test");
The debugger's watch displays a valid hwnd which is the same as _hwnd.
In the spirit of SO, I've tried to condense the code above to a smaller example; however, I cannot reproduce it.
struct Bar {
static int baz() {
int i;
i = 2;
if (false)
throw "";
}
int i;
Bar() :
i(baz()) {
}
};
When running:
Bar bar;
Bar's i value is still 0.
I'd like an explanation why the Windows class example actually returns a valid hwnd, and why the compiler does not fail when not supplying a return statement.