0

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?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Thomas S.
  • 5,804
  • 5
  • 37
  • 72
  • 1
    The example functions you name use a shell to execute. Have a look at `execv()` and friends. – marcolz Apr 25 '18 at 06:33
  • May as well ask why the sun rises in the east. – Tanveer Badar Apr 25 '18 at 06:33
  • 1
    *Why the parameters are not specified as array, too?* but why they must ? the command line as single string the most native option. and entry point of exe have `ULONG __stdcall ep(PEB*)` signature. `main` not a entry point – RbMm Apr 25 '18 at 07:42
  • You are comparing the C standard to the Windows API. These aren't comparable. The question is a bit of a non sequitur. – David Heffernan Apr 25 '18 at 10:30

1 Answers1

4

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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Are there convenience methods that split a command line string into its parts or escapes the parts to get a command line string? – Thomas S. Apr 25 '18 at 06:47
  • 1
    @ThomasS. See [Win32 API command line arguments parsing](https://stackoverflow.com/q/12689142/440558). – Some programmer dude Apr 25 '18 at 06:51
  • 2
    *"In Windows all programs really start with the WinMain function."* - That's not entirely correct. The entry point for all Windows applications is `DWORD EntryPoint()`. The compiler runtime support library performs its initialization, and dispatches to the correct user-provided entry point. Using default settings and the Microsoft Compiler, there is no `WinMain` when targeting the `CONSOLE` subsystem. – IInspectable Apr 25 '18 at 07:35
  • 1
    @IInspectable Reworded answer, quite considerably. – Some programmer dude Apr 25 '18 at 07:47
  • 1
    @IInspectable - yes, in general this is true, but if want be 100% exactly - the signature of exe entry point is `DWORD __stdcall EntryPoint(PEB*)` but if we use `DWORD EntryPoint()` - this also will be work without problems – RbMm Apr 25 '18 at 07:49
  • 1
    *Instead the compiler tells the linker to use a special function* - no, usually compiler (say cl.exe) nothing tell the linker about entrypoint/ the `/ENTRY` this is linker, not compiler option. we direct tell the linker entry point (not via compiler) or linker select it by default based on subsystem – RbMm Apr 25 '18 at 07:55
  • ...`EntryPoint` should not return, it must call `ExitProcess`. – Anders Apr 25 '18 at 09:35
  • @Anders - usual yes, but not mandatory. another thread can call `ExitProcess`. – RbMm Apr 25 '18 at 09:42
  • It is pretty mandatory that a generic `EntryPoint` function calls `ExitProcess`. I don't even think the PE docs say what happens if you return. – Anders Apr 25 '18 at 09:49
  • 1
    @Anders - the any thread of process can call `ExitProcess`. absolute not mandatory that this will be the first thread (which started from entry point). what happens if entrypoint return - `ExitThread` will be called with return value. dont know about docs, what i say is by fact (current implementation in all windows versions) – RbMm Apr 25 '18 at 09:57