8

Possible Duplicates:
main(int argc, char *argv[])
Main's Signature in C++

If i write:

int main(int argc, char** argv)

i get proper commandline input. What would happen if i wrote say,

int main(int foo, double fooDouble, fooType FooVar)

Is this OS-dependent or does it depend on the compiler?

Community
  • 1
  • 1
Tim
  • 834
  • 2
  • 12
  • 31
  • possible duplicate of [main(int argc, char *argv\[\])](http://stackoverflow.com/questions/3898021/mainint-argc-char-argv) and http://stackoverflow.com/questions/3734111/what-are-the-arguments-to-main-for and http://stackoverflow.com/questions/3024197/what-does-int-argc-char-argv-mean –  Jun 30 '11 at 12:11
  • possible duplicate of [Main's Signature in C++](http://stackoverflow.com/questions/1621574/mains-signature-in-c) and [How many arguments does main() have in C/C++](http://stackoverflow.com/questions/2525183/how-many-arguments-does-main-have-in-c-c) – Frerich Raabe Jun 30 '11 at 12:16
  • see also here: http://stackoverflow.com/questions/5282151/can-we-overload-main-function-in-c – davka Jun 30 '11 at 12:16
  • 5
    @Marcelo: "Why don't you try it?" is never a valid answer for undefined behavior, and in fact it's actively harmful advice if left unqualified. -1 to comment if I could... – R.. GitHub STOP HELPING ICE Jun 30 '11 at 12:16
  • 3
    @R: I find such experimentation quite enlightening, actually: http://codepad.org/e6RZyBKQ. – Marcelo Cantos Jun 30 '11 at 12:20

4 Answers4

6

Given that it does compile, it will still only be called with the argc and argv arguments.

So your fooDouble will get the pointer value of argv, and FooVar will get whatever value is in that register/stack space used for that argument position (which may not have been initialized by the callee, so it may hold any undefined value).

Kaos
  • 984
  • 7
  • 17
  • Although you can call main() from anywhere within your program, just like any other function, passing whatever the prototype allows. – cdarke Jul 01 '11 at 05:27
  • @cdarke: No you can not, the standard says you shall not call `main`. – Xeo Jul 01 '11 at 05:33
  • Hmm, g++ seems to compile and run a program with a call to main(int, char **) without any errors... is that a bug in g++? – Jeremy Friesner Jul 01 '11 at 05:39
  • @Xeo, I'd say you still can, even if it is to be avoided. As you say _"you shall not"_, doesn't mean you can't. – Kaos Jul 01 '11 at 08:33
5

This code doesn't even have to compile. If it does, undefined behaviour may occur.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • ooh, shiny undefined behavior ;) – Tim Jun 30 '11 at 12:10
  • It's true that `undefined behaviour may occur`; however, the standard does allow alternative platform-dependant signatures in addition to the two standard onse. – Frerich Raabe Jun 30 '11 at 12:13
  • Doesn't QT have a different main() signature? –  Jun 30 '11 at 12:20
  • 4
    @0A0D: No, it doesn't really. I have the regular one it most of my apps. However, it defines a static library (qmain.lib on windows) which normalizes things (I think it's a workaround for the windows-specific WinMain().) – Macke Jun 30 '11 at 12:35
5

The effect of adding a third (or fourth, or fifth...) argument to main indeed depends on the operating system. For instance, on Windows (and I believe on Unix as well) you can have a third argument which grants access to the environment variables:

int main( int argc, char **argv, char **env )
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
2

The C standard (BS ISO/IEC 9899:1999) gives two alternatives for main:

int main(void) { /* ... */ }

and

int main(int argc, char *argv[]) { /* ... */ }

It also allows equivalents, so an argv of char ** argv for example. Additional arguments are "neither blessed nor forbidden by the Standard". Such addtions will be compiler and runtime (not operating system) specific.

The arguments are passed by the C runtime, which calls main(). Passing any other type would be problematic on general environments like Windows and UNIX, so quite how you would expect to pass a double or fooType is beyond me.

Invoking a program from either a command-line or using interfaces like execve (UNIX) or CreateProcess (Win32) involves passing zero delimited strings. In theory you could hack it to pass a binary value and then cast it in main, provided it does not contain a '\0' anywhere except at the end, which would be challenging.

EDIT: it occurs to me that you can call main() from within your program - the well known obvuscated C code "The twelve days of Christmas" does this. In this case there is no reason why you can pass anything the prototype allows.

cdarke
  • 42,728
  • 8
  • 80
  • 84