6

Problem

Why would compiling a program which has an int main(void) main function differ from compiling a program which has an int main(int argc, char *argv[]) main function, if the program does not use arguments passed on the command line?

Is this OS or compiler specific? I do not get the same results using mingw and g++(which is weird isn't it as wingw is a port of gcc).


Example

Code

#include <iostream>
#include"SDL/SDL.h"
int main(void)
{
    return 0;
}

Compilation commands

g++ test.cpp; #g++ 4.4.5
i586-mingw32msvc-g++ test.cpp; # mingw 4.4.4

Error

(Given by the second command.)

a(main.o):(.text+0x85): undefined reference to `_WinMain@16'
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
danjjl
  • 432
  • 1
  • 5
  • 16
  • 1
    It's compiler specific ... but `int main (int argc, char *argv[])` is "correct". I would recommend *ALWAYS* using the latter form in *ALL* your C and C++ code. – paulsm4 Dec 29 '11 at 21:01
  • @paulsm4: `int main(void)` is also correct. – James McNellis Dec 29 '11 at 21:01
  • http://stackoverflow.com/questions/3156423/why-dont-we-use-void-in-main – paulsm4 Dec 29 '11 at 21:03
  • 1
    Please provide an example program, the exact command you use to invoke the compiler, the exact output of the compiler, and the kind and version of the compiler. Without this information, no one can definitively answer your question. – James McNellis Dec 29 '11 at 21:03
  • You might consider telling us something a bit more specific than it "fails". Compile error (if so, what's the message?) Linker error (if so, what's the message?) Error at runtime (if so, what?) As it stands, people can just guess. – Ernest Friedman-Hill Dec 29 '11 at 21:05
  • In C++ the empty argument list is spelled () instead of (void). The standard mandates that the signatures " int main()" and "int main(int, char *[])" are supported. – Dietmar Kühl Dec 29 '11 at 21:05
  • If you don't use `argc` or `argv`, compiling `int main(int argc, char *argv[])` would give a warning about unused arguments, while `int main()` wouldn't. So that's an obvious difference. Seriously, what difference have you observed? – Daniel Fischer Dec 29 '11 at 21:05
  • What compiler you're using? which version? I don't get any errors, or you might wanna show your whole code. – Mr.Anubis Dec 29 '11 at 21:11
  • @DietmarKühl: However, because "The parameter list (void) is equivalent to the empty parameter list" (C++11 §8.3.5/4), `int main()` and `int main(void)` are equivalent. – James McNellis Dec 29 '11 at 21:12
  • Best practice is always to use int main ( int argc, char *argv[] ) The other forms ( int main () and int main (void)) are allowed by the standard only to accomodate stone-age programs that used them, as I understand it. – Pete Wilson Dec 29 '11 at 21:13

2 Answers2

11

This is SDL thing. On Windows, when you include SDL.h,main is redefined to SDL_main which calls WinMain (the real entry point in non-console Windows apps), does some initialization and finally calls your main code. It has a signature with argc and argv and you're pretty much required to follow it, so int main() won't work.

jrok
  • 54,456
  • 9
  • 109
  • 141
  • (I edited incorrectly -> re-edited) Why would it work with g++ then? – danjjl Dec 29 '11 at 21:52
  • @danjjl Because it's only redefined on Windows. (You're compiling with g++ on some other platform, I assume) – jrok Dec 29 '11 at 21:58
  • Nice :), where did you find the information? is this still true in my example that does not really use SDL? – danjjl Dec 29 '11 at 22:00
  • It's mentioned in FAQ section on SDL's website and there are numerous threads about this issue in their forums. – jrok Dec 29 '11 at 22:06
  • Right it was because I was not linking SDL (event do I would have thought I did not need to as it was not being used). Linking SDL gives `Undefined reference to 'SDL_main'` which is covered in the [FAQ](http://wiki.libsdl.org/moin.cgi/FAQWindows?action=fullsearch&context=180&value=main%28void%29&titlesearch=Titles#I_get_.22Undefined_reference_to_.27SDL_main.27.22_...) – danjjl Dec 29 '11 at 22:14
  • **-1** re "the real entry point in non-console Windows apps" is incorrect. it's not an entry point. and notwithtanding Microsoft's botched documentation about this (it's infamous) there's no difference of entry point for console and gui subsystem apps. what there is, is a difference in defaults for Microsoft's own linker. that's a tool problem, and is irrelevant to SDL's very nasty code. – Cheers and hth. - Alf Jul 05 '14 at 13:44
-1

The specification of main(...) is a contract. In the C language, the contract says that the arguments are int and char **. This is a requirement your program has to fulfill, if it wants the environment to interact with it.

Whether or not your program wants to use the parameters is a different issue -- it just has to abide by the contract that there is a functiona named main, with the correct order and type of parameters.

Juha Laiho
  • 596
  • 2
  • 8
  • 2
    This question is about C++, not C. That said, this answer is incorrect regardless: `int main(void)` is a perfectly valid declaration of `main` in both C (C90, C99, and C11) and C++ (C++98, C++03, and C++11). – James McNellis Dec 29 '11 at 21:11