shawn-young
shawn-young

Reputation: 81

What exactly the bad consequences are when using `main()` instead `WinMain()` in a Windows GUI application?

There is an article about entry point on MSDN which contains a warning about using main() instead of WinMain().

The CRT does some additional work inside main. For example, any static initializers are called before wWinMain. Although you can tell the linker to use a different entry-point function, use the default if you link to the CRT. Otherwise, the CRT initialization code will be skipped, with unpredictable results. (For example, global objects will not be initialized correctly.)

Unfortunately I could't find any information about what exactly the bad consequences are if I use main() instead of WinMain() in an application with windows subsystem setting.

Does anyone can tell, or how can I find it out on my own ? Sincerely thank you!

Upvotes: 0

Views: 400

Answers (2)

Anders
Anders

Reputation: 101764

You can't really trust that documentation, main does not call WinMain. The issue it is trying to warn against is when you override the CRTs entry point function with the /ENTRY linker switch. If you do that then the CRT is not going to be initialized correctly and constructors might not be called.

At the Windows ABI layer, if IMAGE_OPTIONAL_HEADER.Subsystem is set to IMAGE_SUBSYSTEM_WINDOWS_CUI then a new console/terminal is created unless the parent process already has a console. The caller of CreateProcess can override this with CREATE_NEW_CONSOLE and other flags.

When the process is started, Windows just calls the entry point function (AddressOfEntryPoint) and this function does not have any parameters.

When using the Microsoft linker this function is called mainCRTStartup when creating a console application and WinMainCRTStartup when creating a GUI application. If you are using the C run-time/CRT then these functions are provided for you and call main or WinMain respectively. Either way, the special magic is performed before your entry point function is called.

A console application is allowed to create normal windows and a GUI application can create consoles (AllocConsole). Which type you choose just depends on if you want a console to be created for you. Additional work is required if you want to associate stdout with a console you manually create.

My recommendation is to just use main in your code for console applications and WinMain in GUI applications, the linker and CRT will take care of the rest.

Upvotes: 3

Adrian McCarthy
Adrian McCarthy

Reputation: 48038

The answer is right in the quote. CRT initialization code won't run, so its global objects won't be initialized. The CRT initialization code is also responsible for initializing your program's global objects, so they won't be initialized either.

Anything that depends on this initialization may fail or misbehave. Nobody's going to document all the specifics of what those are, because it's going to vary by implementation. But you could easily imagine things like heap allocation (malloc, free, new, delete, etc.) depend on initialization, as might i/o to the standard handles (stdout, cout, etc.) You cannot come up with a complete list, but it should be obvious that depriving important subsystems of their initialization is going to make it very difficult to build a working, non-trivial program.

Since you seem to be asking specifically about Windows, I'll assume you're using Visual C++ and its runtime libraries. Note that Visual C++ includes the sources of the runtime libraries. You can step through the initialization code in the debugger to see the types of work it does before passing control to WinMain.

Upvotes: 1

Related Questions