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:

  1. In listing 1, linker should have complained for missing "main". Why is it looking for _WinMain@16?

  2. The executable generated from listing 2 simply crashes. What is the reason?

Thanks for your time.

share|improve this question
1  
It crashes because dereferencing void (*main)(); executes a NULL pointer (if that is your complete code) – Mawg Feb 14 '10 at 2:48
up vote 4 down vote accepted

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.

share|improve this answer
1  
The compiler usually requires '_WinMain' when developing applications for windows. Many compilers have a console template, which requires main, but doesn't provide all the windowing goodies, just ol' fashioned C. – Thomas Matthews Feb 12 '10 at 19:18
    
Thomas, thanks, that much I know. Just wasn't sure if VS maybe "implants" _WinMain automatically into console programs. – Nikolai Fetissov Feb 12 '10 at 20:19

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.

share|improve this answer
12  
    
+1, didn't know that :) – Daniel Sloof Feb 12 '10 at 14:37

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.

share|improve this answer
    
> The second example defines main, but incorrectly. Does this mean compiler allocates some storage for this code? void (*main)(); Is this not just a declaration, main points to a function that takes an unspecified number of arguments and returns nothing? (as opposed to a definition)? – Gowtham Feb 12 '10 at 14:39
1  
+1 for the post. Can you give example of main declared as an array and the code will work? I am quite curious to know this. Have never come across such a code. – Jay Feb 12 '10 at 14:40
1  
In the olden days, it was easier to do stuff like that. For an example of an executable array see stackoverflow.com/questions/2251859/… – Richard Pennington Feb 12 '10 at 14:53
2  
int main[] = { 0xC3 }; 0x63 is the opcode for RET (return). Surprisingly, this seems to return 1! Not sure where this 1 comes from. ;) – Gowtham Feb 12 '10 at 15:03

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.

share|improve this answer

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.

share|improve this answer

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

share|improve this answer
3  
Function main doesn't need to have arguments. int main(void) is also a perfectly valid signature. However, in C (unlike C++) int main() means that it can take any arguments, which is bad style, but AFAIK still legal. – Tronic Feb 12 '10 at 14:32
    
Agreed (sorry) See en.wikipedia.org/wiki/… But, in any case, he obviously has a linker error because no main function is declared (agreed?). Some environments (especially those for developing GUI based programs) will provide this automagically. – Mawg Feb 14 '10 at 2:49

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.

share|improve this answer
    
Does this mean compiler allocates some storage for this code? void (*main)(); Is this not just a declaration, main points to a function that takes an unspecified number of arguments and returns nothing? (as opposed to a definition)? – Gowtham Feb 12 '10 at 15:10
    
No. it allocate space for a pointer to a function that takes an unspecified number of arguments and returns nothing. char* main; or even void *main; would have accomplished the same thing. – James Curran Feb 12 '10 at 15:43

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.