3

First I should specify that I'm using the clang compiler from Visual Studio. When debugging the following simple program, the WinMain function returns the value of the variable when a peculiar condition seems to be met.

#include <windows.h>    

int CALLBACK WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    int var = 1;
    var = var + 5;
}

The above would output in the debugger: The program '[11396] Project1.exe' has exited with code 6 (0x6). This behavior seems to happen without fail whenever there is a variable name in the right hand expression of the assignment. If I were to modify the last line to assign just a literal such as var = 5, the output would be a consistent unrelated value every time: The program '[4148] Project1.exe' has exited with code -858993460 (0xcccccccc).

I suspect that this behavior has to do with WinMain, because when I use plain-old main() instead, I get the expected return of 0. Any idea as to what could be the cause of this strange behavior?

  • 5
    You are supposed to use `return 0;` in your function to set the exit code. Odd that your compiler does not complain about it, be sure to raise the warning level. – Hans Passant Jul 10 '18 at 23:47
  • I didnt figure that omitting it would cause what seems to be undefined behavior. Apparently most compilers add it when compiling? At least it seems to do so when using `int main()` but not `WinMain()` – Daniel Sadeghi Jul 10 '18 at 23:50
  • 2
    return 0 is optional from main according to the standard. WinMain is obviously not covered in that and not returning a value means you end up with whatever was in that spot on the stack usually, if it doesn't crash. 0xcccc is uninitialized stack memory when using the debug heap in Windows. https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations – Retired Ninja Jul 10 '18 at 23:53
  • This is a quirk of the way this particular compiler's code generation works with the optimisation settings you are using. What is likely happening here is that the new value of `var` is being calculated using the same register as is used for the return value of a function. If you increase the optimisation level sufficiently, I expect you will see this behaviour change. – clstrfsck Jul 10 '18 at 23:54
  • Microsoft's MSDN [guide for WinMain](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633559%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396) says: "If the function terminates before entering the message loop, it should return zero." Those are instructions to you, the developer. – JohnH Jul 11 '18 at 02:07
  • -858993460 = 0xCCCCCCCC which means [you've accessed uninitialized memory](https://stackoverflow.com/q/370195/995714) – phuclv Aug 18 '18 at 11:16

1 Answers1

5

The problem is that you're not explicitly returning ANYTHING.

I guess maybe the fact that you did some arbitrary assignment (var = var + 5) happened to leave a "valid looking" number in the register Windows is using for your return value.

But the fact is: without an explicit return SOMEVALUE;, then your program is exhibiting "undefined behavior".

To check this theory, I urge you to compile with "/Fa", and look at the assembly output :)

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • Thanks for the help :) It's quite interesting that it won't work without it but `int main()` will – Daniel Sadeghi Jul 10 '18 at 23:55
  • "main()" is a "standard C" thing. "WinMain()" is a "Microsoft thing". Simple as that :) Again - I'd definitely encourage you to examine the assembly language output of both, to satisfy your curiosity. Per msandiford's suggestion, you can also change optmization level, and see if the assembly changes. It might :) – paulsm4 Jul 10 '18 at 23:56
  • Will do! Thanks – Daniel Sadeghi Jul 10 '18 at 23:59