In C, main need not be a function?

2019-03-12 19:15发布

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.

标签: c main
8条回答
闹够了就滚
2楼-- · 2019-03-12 19:50

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.

查看更多
爷的心禁止访问
3楼-- · 2019-03-12 19:59

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.

查看更多
forever°为你锁心
4楼-- · 2019-03-12 20:00

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.

查看更多
叼着烟拽天下
5楼-- · 2019-03-12 20:06

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.

查看更多
可以哭但决不认输i
6楼-- · 2019-03-12 20:06

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.

查看更多
成全新的幸福
7楼-- · 2019-03-12 20:07

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

查看更多
登录 后发表回答