As many other answers here point out, the precise mechanism a compiler implementation uses to pass arguments to main is unspecified by the standard (as is the mechanism a compiler uses to pass any arguments to a function). Strictly speaking, the compiler need not even pass anything useful in those parameters, since the values are implementation-defined. But neither of these are particularly helpful answers.
The typical C (or C++) program is compiled for what's known as a 'hosted' execution environment (using function main()
as the starting point of your program is one of the requirements for a hosted environment). The key thing to know is that the compiler arranges things so that when the executable is launched by the operating system, the compiler's runtime gets control initially - not the main()
function. The runtime's initialization code performs whatever initialization is necessary, including allocating memory for the arguments to main()
, then it transfers control to main()
.
The memory for the arguments to main()
could come from the heap, could be allocated on the stack (possibly using techniques that aren't available to standard C code), or could use statically allocated memory, though that's a less likely option just because it's less flexible. The standard does require that the memory used for the strings pointed to by argv
are modifiable and that modifications made to those string persist throughout the program's lifetime.
Just be aware that before execution reaches main()
, quite a bit of code has already been run that's setting up the environment for your program to run in.