Search code examples
cwinapiprogram-entry-point

Unsymmetry between main and launching process


A C main method has the signature

int main(int argc, char** argv) {
}

It will get an array of command line parameters. But when trying to launch an application, e.g. using CreateProcess or ShellExecute, they only accept 2 parameters, one for the application to launch and one for the parameters. Why the parameters are not specified as array, too? Why every application that uses other applications has to deal with escaping of command line parameters, e.g., when invoking a compare tool with 2 arbitrary file names that might contain spaces or quotes?


Solution

  • On very few system the actual program execution actually start at the main (or WinMain) or similar function. Instead the compiler tells the linker to use a special function which usually doesn't really take any arguments, in the C sense of the word.

    The command-line arguments (if any) could be passed through special registers on the assembly level, or they needs to be fetched using special OS-specific functions (like GetCommandLine in the Windows API).

    On Windows, the GetCommandLine function does indeed get the command line as a single string. Just like it was passed to e.g. CreateProcess.

    For a Windows console program, the special "entry" function does some other initialization (like setting up stdin etc.), and then calls GetCommandLine to get the command-line arguments, which it then parses into an array suitable for the main function, which is then called.


    If you look at the POSIX world (where e.g. Linux and macOS lives) then they have the exec family of functions which does indeed take an array for the arguments. Or a variable-argument list which is parsed into such an array.