As far as I know,
main ()
function has the following prototypes:
int main();
int main(int argc, char **argv);
Now, C does not support overloading, then how are multiple prototypes of
main ()
supported?
|
As far as I know,
function has the following prototypes:
Now, C does not support overloading, then how are multiple prototypes of
supported? |
||||
|
As a program can only contain one function called In the call-sequence for As a side note, the last two prototypes are identical and in a function definition, the first two would be identical as well. That leaves only two supported signatures for |
|||||||
|
|
One thing you have to understand about C or any other language that produces native object files is that the only time function prototypes matter is during compilation. By the time the linker sees it, the only thing to be done is fill in the missing addresses of external functions. Arranging the passing of function parameters is entirely up to the compilers, usually based on an architecture-specific convention. Most implementations on machines with stacks push the parameters in reverse order followed by the return address. Ergo, when code wants to call Calling Section 5.1.2.2.1 of the C standard specifically says that no implementation will define a prototype for As you might have guessed, this trick only works in the direction of a caller calling a function with more arguments than the called function consumes will just have pushed on more than the caller will see. A called function with more parameters than the caller pushed will simply look further down the stack than it should and fall victim to the GIGO principle. Since the caller undoes the adjustment to the stack pointer, the stack comes out of it unscathed after the called function returns. Addendum, addressing Bart van Ingen Schenau's comment: C++ mangles its symbol names to prevent collisions between same-named, differently-prototyped functions, as almost every native object file format on the planet differentiates symbols only by name. That has the pleasant side effect of preventing mismatched calls between C++ object files, but only because a C++ compiler compiling a wrongly-prototyped call will emit a symbol that won't be present in the object file that would contain the called function. It happens that you get human-readable C++ function names in linker error messages because many of them recognize and demangle C++ symbols. An object file can refer to a C++ function in another object file by its mangled name and attempt to call it. (I've actually done this experimentally and would never in a million years condone doing it in "real" code.) The linker, which has no idea whether either object was produced by a C++ compiler or from some bit of hand-written assembly, will do nothing to prevent it as long as the symbol names match. That makes the assertion that the linker plays any direct role in enforcing C++ language policies erroneous. |
|||||
|
|
If you define a function named
You're defining Similarly, you're defining ( As for why those two are permitted, rather than, say, requiring exactly the second form, it's mostly for historical reasons. Early C compilers didn't have prototypes (they were introduced in the 1989 C standard, borrowed from C++). In pre-standard C, defining
probably just meant that the calling environment would pass For historical reasons, modern calling conventions are likely to work similarly, but since the 1989 ANSI standard compilers have been permitted to make the two forms incompatible -- but if they are, then the implementation has to do whatever is necessary to make both forms work. |
|||
|
|
C does support overloading, it doesn't support user defined overloading of functions but operators have a fixed set of standard defined overloads.
The compiler has to do the right things for different possible definitions of BTW, note that has your two last lines are strictly equivalent and the difference between the two first may occurs in valid programs for other functions than main. |
|||
|
|
int main()is valid; the standard shows it asint main(void). (C++ permitsint main(), but it has a different meaning than it has in C.) – Keith Thompson Mar 2 at 20:11