Reputation: 1485
This code compiles, but no surprises, it fails while linking (no main found):
Listing 1:
void main();
Link error: \mingw\lib\libmingw32.a(main.o):main.c:(.text+0x106) undefined reference to _WinMain@16'
But, the code below compiles and links fine, with a warning:
Listing 2:
void (*main)();
warning: 'main' is usually a function
Questions:
In listing 1, linker should have complained for missing "main". Why is it looking for _WinMain@16?
The executable generated from listing 2 simply crashes. What is the reason?
Thanks for your time.
Upvotes: 14
Views: 8830
Reputation: 44814
On Windows platforms the program's main unit is WinMain if you don't set the program up as a console app. The "@16" means it is expecting 16 bytes of parameters. So the linker would be quite happy with you as long as you give it a function named WinMain with 16 bytes of parameters.
If you wanted a console app, this is your indication that you messed something up.
Upvotes: 3
Reputation: 1
1.) An (compiler/platform) dependent function is called before code in main is executed and hence your behavior(_init
in case of linux/glibc).
2) The code crash in 2nd case is justified as the system is unable to access the contents of the symbol main
as a function which actually is a function pointer pointing to arbitrary location.
Upvotes: 0
Reputation: 103605
In listing 1, you are saying "There's a main() defined elsewhere in my code --- I promise!". Which is why it compiles. But you are lying there, which is why the link fails. The reason you get the missing WinMain16 error, is because the standard libraries (for Microsoft compiler) contain a definition for main(), which calls WinMain(). In a Win32 program, you'd define WinMain() and the linker would use the library version of main() to call WinMain().
In Listing 2, you have a symbol called main defined, so both the compiler & the linker are happy, but the startup code will try to call the function that's at location "main", and discover that there's really not a function there, and crash.
Upvotes: 0
Reputation: 100196
You declared a pointer-to-function named main, and the linker warned you that this wouldn't work.
The _WinMain message has to do with how Windows programs work. Below the level of the C runtime, a Windows executable has a WinMain.
Upvotes: 2
Reputation: 19985
In most C compilation systems, there is no type information associated with symbols that are linked. You could declare main as e.g.:
char main[10];
and the linker would be perfectly happy. As you noted, the program would probably crash, uless you cleverly initialized the contents of the array.
Your first example doesn't define main, it just declares it, hence the linker error.
The second example defines main, but incorrectly.
Upvotes: 7
Reputation: 84239
Case 1. is Windows-specific - the compiler probably generates _WinMain
symbol when main
is properly defined.
Case 2. - you have a pointer, but as static variable it's initialized to zero, thus the crash.
Upvotes: 5
Reputation: 10430
True, main
doesn't need to be a function. This has been exploited in some obfuscated programs that contain binary program code in an array called main
.
The return type of main() must be int
(not void
). If the linker is looking for WinMain
, it thinks that you have a GUI application.
Upvotes: 32
Reputation: 40215
Try redefining it as int main(int argc, char *argv[])
What you have is a linker error. The linker expects to find a function with that "signature" - not void with no parameters
See http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html etc
Upvotes: 1