0

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.

Michael Choi
  • 610
  • 5
  • 22
  • `if (false) throw "";` is this supposed to be `if (true) throw "";` ? otherwise I dont understand the question... – 463035818_is_not_an_ai Apr 16 '19 at 16:23
  • in the code as posted the `throw` is a red herring and the ub is from not returning anything when the function should return an `int` – 463035818_is_not_an_ai Apr 16 '19 at 16:24
  • 1
    _"Flowing off the end of a value-returning function (except main) without a return statement is undefined behavior."_ source: https://en.cppreference.com/w/cpp/language/return – Richard Critten Apr 16 '19 at 16:25
  • @user463035818 It is correct as it is in the example. I don't want it to throw. I should have clarified, the function only compiles if a throw is introduced, which is why there is a dead branch with a throw. – Michael Choi Apr 16 '19 at 16:25
  • 1
    Sort of the answer (minus the "know-it-all" designation): https://stackoverflow.com/questions/2235457/how-to-explain-undefined-behavior-to-know-it-all-newbies/2236839#2236839 – Ben Voigt Apr 16 '19 at 16:27
  • @RichardCritten and Bob's your uncle. Thanks for the speedy reply. I'm going to format it into an answer if you don't mind. – Michael Choi Apr 16 '19 at 16:27
  • There is no return in your foo, are you sure it will compile correctly?? – Tony Apr 16 '19 at 16:28
  • 1
    ah ok sorry, my fault. completely misread the question ;). You already know that it is missing the `return` and you can silence the warning by adding the `if (false) throw` and try to understand the results you get, right? Trying to understand what happens in the presence of UB usually does not bring much insight, after all it is still UB and needs to be fixed – 463035818_is_not_an_ai Apr 16 '19 at 16:28
  • @Tony yes, I've compiled it in visual studio 2015 – Michael Choi Apr 16 '19 at 16:28
  • @user463035818 yes that's exactly it. – Michael Choi Apr 16 '19 at 16:29
  • @JesperJuhl I realize that, I was asking about the compilation of the code above, not what undefined behavior is. – Michael Choi Apr 16 '19 at 16:41

0 Answers0