Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » undefined reference to 'WinMain@16'

This thread is locked; no one can reply to it. rss feed Print
undefined reference to 'WinMain@16'
levizil
Member #9,925
June 2008

Just seeing if someone here could help me out. I've been trying to set up code::blocks with allegro and got it to run, but I don't think it's right. The book that I'm reading on allegro gives a test program to see if allegro is working right.

#include <conio.h>
#include <stdlib.h>
#include "allegro.h"

#include <conio.h>
#include <stdlib.h>
#include "allegro.h"

int main()
{
allegro_init();
printf("Allegro version = %s\n", allegro_id);
printf("\nPress any key...\n");
getch();
return 0;
}
END_OF_MAIN;

This, however, gives a 'undefined reference to WinMain@16' linker error. So I changed main to WinMain and it compiles and runs fine. I was wandering if coding it with the WinMain ruins the crossplatforminess of allegro and if it does, why does it try to use WinMain as a entry point.

using vista, Allegro 4.2.1, mingw 3.4.5, and the gcc compiler with Code::Blocks nightly build

||=== allgtest, Debug ===|
C:\MinGW\share\CodeBlocks\myprograms\allgtest\main.c||In function `_mangled_main':|
C:\MinGW\share\CodeBlocks\myprograms\allgtest\main.c|8|warning: implicit declaration of function `printf'|
C:\MinGW\share\CodeBlocks\myprograms\allgtest\main.c|13|warning: type defaults to `int' in declaration of `END_OF_MAIN'|
C:\MinGW\share\CodeBlocks\myprograms\allgtest\main.c|13|warning: data definition has no type or storage class|
\mingw\lib\libmingw32.a(main.o):main.c:(.text+0x106)||undefined reference to `WinMain@16'|
||=== Build finished: 1 errors, 3 warnings ===|

Evert
Member #794
November 2000
avatar

Quote:

The book that I'm reading on allegro gives a test program to see if allegro is working right.

The book you're reading has known bugs and problems, so beware.

Anyway, it's END_OF_MAIN(), not END_OF_MAIN; (or END_OF_MAIN(); for that matter).

Quote:

I was wondering if coding it with the WinMain ruins the crossplatforminess of allegro

Yes, it does.

Quote:

and if it does, why does it try to use WinMain as a entry point.

You have to, if you want to write a Windows GUI application (blame Microsoft). Allegro uses a trick that allows you to write a regular main() function instead of WinMain (if you want the details: through END_OF_MAIN() Allegro defines a WinMain function that calls your main() function).

EDIT: other problems associated with that book: conio.h and any functions defined by it. Avoid these like teh plague, they're not portable and cannot (and most definately shouldn't) be used reliably alongside Allegro.

levizil
Member #9,925
June 2008

Thanks for responding. I put the () in the end of main and it works now.

torhu
Member #2,727
September 2002
avatar

I don't think you really need WinMain to get a Windows GUI app. A regular main is ok. To disable the console window, you add "subsystem:windows" to the linker's command line.

axilmar
Member #1,204
April 2001

If you add 'subsystem:windows', the linker will search for WinMain as the application's entry point, methinks.

anonymous
Member #8025
November 2006

If I'm not mistaken, "Undefined reference to WinMain@16" is just Mingw's way to report that the linker didn't find main (or WinMain). (If it is not there, how's it supposed to know which it should be.)

Evert
Member #794
November 2000
avatar

Quote:

I don't think you really need WinMain to get a Windows GUI app. A regular main is ok.

If that were true there'd be no need for Allegro's magic main mangling.
I remember we tried this a couple of years ago. As far as I recall, what you say is true for MinGW, but it is not true of MSVC. Unfortunately.

torhu
Member #2,727
September 2002
avatar

Here's a way to get away with using main() with msvc. Seems that if you link with "/ENTRY:mainCRTStartup", it won't look for WinMain. I haven't tested it, though.

Here's an article about opening and using a console window from a GUI app. Shows that you don't have to decide at link time if you want GUI or console. It's just a bit more work to get some flexibility.

EDIT:
I had a second look at this. It seems MinGW and DMC don't care about whether you use main or WinMain, but MSVC does. It's easy to fix that, though.

All that's required is to add this in a header:

#if _MSC_VER
   #pragma comment(linker,"/ENTRY:mainCRTStartup")
#endif

Or to the command line, or in Visual Studio project options.

I've attached exhello.c modified to test this stuff.

Docs:
http://msdn.microsoft.com/en-us/library/f9t8842e(VS.71).aspx

Maybe dumping WinMain could be an option for allegro 5? I know that there's some startup code being run from Allegro's main on OS X, but maybe that could be run by allegro_init or something.

Getting rid of the END_OF_MAIN macro sure wouldn't hurt.

Evert
Member #794
November 2000
avatar

Quote:

Getting rid of the END_OF_MAIN macro sure wouldn't hurt.

Exactly.

Quote:

I had a second look at this. It seems MinGW and DMC don't care about whether you use main or WinMain, but MSVC does.

Right, that fits with what I know. Did you check the Intel or Borland compilers (and whatever else Allegro supports in Windows)?

Quote:

All that's required is to add this in a header:

#if _MSC_VER
#pragma comment(linker,"/ENTRY:mainCRTStartup")
#endif

Or to the command line, or in Visual Studio project options.

Yeach, pragma's. Well, it beats forcing people to use a particular linker option with Allegro, and it makes it easier to implement ALLEGRO_NO_MAGIC_MAIN.
Do you know whether this works in all versions of MSVC, or just recent ones?

One final request: could you put up a post with this information in de development forum, or the mailing list? Thanks.

torhu
Member #2,727
September 2002
avatar

It works with msvc 6 and 9, and Intel's latest compiler. I noticed that Intel uses the msvc linker, and choosing the entry point is done by the linker anyway.

I haven't got Borland, Watcom or djgpp installed. Not sure what exactly Allegro 5 is supposed to support either.

I'll post about this on the mailing list later.

Evert
Member #794
November 2000
avatar

Quote:

It works with msvc 6 and 9, and Intel's latest compiler. I noticed that Intel uses the msvc linker, and choosing the entry point is done by the linker anyway.

Ok, great!

Quote:

I haven't got Borland, Watcom or djgpp installed.

I meant Borland for Windows, I thought Allegro worked with that, but I could remember incorrectly. Don't care about DOS (END_OF_MAIN() doesn't do anything in DOS anyway).

Quote:

Not sure what exactly Allegro 5 is supposed to support either.

I think MSVC and MinGW are the obvious targets, but the more the better, of course.

Quote:

I'll post about this on the mailing list later.

Great, thanks!

GullRaDriel
Member #3,861
September 2003
avatar

That has been discussed more than necessary.

I am always astonished by the amount of answer that are already sitting somewhere on the forum...

And how people don't manage to use the SEARCH button !

Well, that does not matter anyway because people generally just ignore my statements.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

Well, that does not matter anyway because people generally just ignore my statements.

Thats because you don't bother reading what you're replying too ::)

Most of that "unecessary" discussion was about how to get rid of END_OF_MAIN, and not the original OP's question. ::)

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

torhu
Member #2,727
September 2002
avatar

I wouldn't mind if a moderator would split this topic in two, starting with my first post, and put the END_OF_MAIN discussion in the allegrodev forum. Then again, I don't know if that's even possible.

GullRaDriel
Member #3,861
September 2003
avatar

Thomas, please do not say I did not read the topic, because I did .

OTOH, you did NOT read correctly. The OP had a problem with END_OF_MAIN because he did not wrote it correctly. Wait, what do I see all along these search pages ? END_OF_MAIN() !

Incredible, no ?

As it's not the first time you quote me and search what's wrong, I think you have something against me. Yeah, I am that way.

I gave an incomer a good information, it's that there are people that already had the same problem as him, it's commonly the case, and to continue the magic there is a search page and even some tags to add links in your post !

Now, to the quote part:

Thomas said:

Thats because you don't bother reading what you're replying too ::)

In our talk you are the only one to assume that statement.

Thomas said:

Most of that "unecessary" discussion was about how to get rid of END_OF_MAIN, and not the original OP's question. ::)

You DO noticed that my post was aimed to the OP, there is no way I was answering the troll that have (as usual) came after the few OT answers.

(To the OP: read this to make your post looking better)

PS: I just noticed that the ::) smiley is in fact somewhat a smiling alien : : )

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

OTOH, you did NOT read correctly. The OP had a problem with END_OF_MAIN because he did not wrote it correctly. Wait, what do I see all along these search pages ? END_OF_MAIN() !

That was answered already. And the thread had moved on. Notice you can't specify that you are replying directly to the original post using the post form, you are in fact taking part of a linear discussion. One which can, and will change.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

GullRaDriel
Member #3,861
September 2003
avatar

You can't admit that posting about using the search button just aim the new comer and not people who are used to allegro and the a.cc forum, can't you ?

I know that was already answered, and if you read correctly my post you will notice the fact that the word 'search' is all upper case, because I wanted to put the accent on the 'search before ask' thing, and not on the answer (which was as you said already answered). When I gave a link to a search page that was On Topic, I was giving a hint, so why give a half cut hint ?

Thomas said:

One which can, and will change.

My English knowledge is too weak to understand that statement.

Anyway, we are both keeping our position so the situation wont change until one move.

As I don't like it that way and don't want to have and endless talk about that silly subject, let's say that we are both right:

I should have told at the beginning of my post something like "To the OP:", and you shouldn't have taken that post for you or another regular member who knows that the answer is generally already sitting in the forum.

It's a closed debate for me.

Regards, Gull.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Evert
Member #794
November 2000
avatar

Quote:

Then again, I don't know if that's even possible.

No.

Quote:

Wait, what do I see all along these search pages ? END_OF_MAIN() !

Yes, and you see the same thing anywhere else, including the book that piece of code is from (well, I think that has END_OF_MAIN(); but never mind). So in fact the OP should have been able to spot it from looking at the source he got his code from. Since he obviously didn't, the most logical thing to do was to point out the error directly rather than say something along the lines of "you make a typo, but I'm not going to tell you where it is, look it up yourself you lazy noob."

Anyway, I'd rather talk about getting rid of END_OF_MAIN().

GullRaDriel
Member #3,861
September 2003
avatar

Evert said:

Yes, and you see the same thing anywhere else, including the book that piece of code is from (well, I think that has END_OF_MAIN(); but never mind). So in fact the OP should have been able to spot it from looking at the source he got his code from. Since he obviously didn't, the most logical thing to do was to point out the error directly rather than say something along the lines of "you make a typo, but I'm not going to tell you where it is, look it up yourself you lazy noob."

You could also add that no one explained him his compiler output, what would have made him find his error.
While we are at it, let's do it.

||=== allgtest, Debug ===|
C:\MinGW\share\CodeBlocks\myprograms\allgtest\main.c||In function `_mangled_main':    /* the bug sits in the main function */
C:\MinGW\share\CodeBlocks\myprograms\allgtest\main.c|8|warning: implicit declaration of function `printf' /*it means that printf is used before being declared. check that you have #include <stdio.h> at the very beginning of your code. */
C:\MinGW\share\CodeBlocks\myprograms\allgtest\main.c|13|warning: type defaults to `int' in declaration of `END_OF_MAIN' /* the compiler can't find END_OF_MAIN declaration, it default to int */
C:\MinGW\share\CodeBlocks\myprograms\allgtest\main.c|13|warning: data definition has no type or storage class /* Here is the part that should have taken all your attention ! The compiler is crying about the fact that it does not found any END_OF_MAIN declaration. It's common compiler error when you mispelled a variable / function */
\mingw\lib\libmingw32.a(main.o):main.c:(.text+0x106)||undefined reference to `WinMain@16'| /* That one comes from the fact that there is no END_OF_MAIN() at the end of your main() function, and for the reasons given by other people in that post */
||=== Build finished: 1 errors, 3 warnings ===| 

Quote:

Anyway, I'd rather talk about getting rid of END_OF_MAIN().

That's a good point, but... I do not care writing END_OF_MAIN() at the end of all my projects. It's just 13 char... or a copy paste from another source ... Or perhaps it is just sitting in my simple skeleton for starting a project ? Well, it does not matter. If it disappear, then I will erase it from my projects.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Go to: