Neither main/WinMain/wmain/wWinMain are actually the methods called on program launch. Both are preceded by various setup calls (i.e. the CRT in your mainCRTStartup linker flag).
The pre-main runtime doesn't do much, but it does initialize the WinMain parameters in not that a fashion not that dissimilar from your example. You could just do all that work yourself, but really, why should you? On most platforms you can get argc and argv[] through the right system calls and file I/O as well, but it's much easier to have the conventional runtime do all that stuff for you.
WinMain is just a convention (https://devblogs.microsoft.com/oldnewthing/20061204-01/?p=28...) for your C/C++/etc runtime to start executing the code you write. Linux isn't all that different, adding runtime code before the main() method where necessary.
This only applies to C++, but the CRT runs all constructors of global variables before main/WinMain. (Or rather, the CRT calls a special function that the compiler generates for this purpose and links into the executable.) In some codebases, that's quite a lot of stuff.
There is also initialization relevant for C code, e.g. strlen() will crash if you call it from the startup function directly without properly initializing msvcrt.
> On most platforms you can get argc and argv[] through the right system calls
Not (reliably) on Linux or, as far as I know, on similar systems. argv, environ, and the aux vector come from a horrible data structure the kernel creates on the stack.
The kernel just copies the data to the program's stack in a contiguous manner. Obtaining pointers to them can seem somewhat magical if you're writing a nolibc program but I wouldn't call it horrible.
I implemented it for my programming language with some rather simple assembly code:
I’m saying you can’t reliably get the information from syscalls. The runtime (i.e. whatever implements the actual entry point declared in the ELF headers) can get it reliably, as can any other code to which the runtime gives an appropriate pointer.
You can’t assume that /proc is procfs if you’re writing a low level runtime library.
If you can find the top of the stack, you can read the contents with reasonable reliability. But the top of the stack is not at a fixed address, and if you are writing low enough level code (container manager, init, etc), poking around in /proc at startup is not a great idea.
If you’re wiring a real runtime library, none of this matters: the kernel passes a pointer in a register at startup.
The pre-main runtime doesn't do much, but it does initialize the WinMain parameters in not that a fashion not that dissimilar from your example. You could just do all that work yourself, but really, why should you? On most platforms you can get argc and argv[] through the right system calls and file I/O as well, but it's much easier to have the conventional runtime do all that stuff for you.
WinMain is just a convention (https://devblogs.microsoft.com/oldnewthing/20061204-01/?p=28...) for your C/C++/etc runtime to start executing the code you write. Linux isn't all that different, adding runtime code before the main() method where necessary.