繁体   English   中英

在C中,主要不需要功能吗?

[英]In C, main need not be a function?

这段代码可以编译,但不会令人惊讶,它在链接时失败(未找到主要代码):

清单1:

void main();

链接错误:\\ mingw \\ lib \\ libmingw32.a(main.o):main.c :(。text + 0x106)对_WinMain @ 16的未定义引用

但是,下面的代码可以编译和链接,但带有警告:

清单2:

void (*main)();

警告:“ main”通常是一个函数

问题:

  1. 在清单1中,链接器应该抱怨缺少“ main”。 为什么要寻找_WinMain @ 16?

  2. 从清单2生成的可执行文件完全崩溃。 是什么原因?

谢谢你的时间。

的确, main不必是一个函数。 在一些混淆的程序中利用了这一点,这些程序在名为main的数组中包含二进制程序代码。

main()的返回类型必须为int (不是void )。 如果链接程序正在寻找WinMain ,则认为您有一个GUI应用程序。

在大多数C编译系统中,没有与链接的符号关联的类型信息。 您可以将main声明为例如:

char main[10];

链接器将非常高兴。 如您所述,程序可能会崩溃,除非您巧妙地初始化了数组的内容。

您的第一个示例未定义main,而是对其进行了声明,因此出现了链接器错误。

第二个示例定义了main,但定义不正确。

情况1.是特定于Windows的-正确定义main ,编译器可能会生成_WinMain符号。

情况2-您有一个指针,但是作为静态变量, 它被初始化为零 ,从而导致崩溃。

在Windows平台上,如果未将程序设置为控制台应用程序,则该程序的主要单元为WinMain。 “ @ 16”表示期望16个字节的参数。 因此,只要您给它一个名为WinMain的函数并带有16个字节的参数,链接器就会对您很满意。

如果您想要控制台应用程序,则表明您搞砸了。

您声明了一个指向main的函数指针,链接器警告您这行不通。

_WinMain消息与Windows程序的工作方式有关。 在C运行时级别之下,Windows可执行文件具有WinMain。

尝试将其重新定义为int main(int argc, char *argv[])

您所拥有的是链接器错误。 链接器希望找到具有该“签名”的函数-没有参数的无效

参见http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html

在清单1中,您说的是“在我的代码的其他地方定义了一个main(),我保证!”。 这就是为什么它会编译。 但是您躺在那里,这就是链接失败的原因。 之所以会丢失WinMain16错误,是因为标准库(对于Microsoft编译器)包含main()的定义,该定义调用WinMain()。 在Win32程序中,您将定义WinMain(),链接器将使用main()的库版本来调用WinMain()。

在清单2中,您有一个称为main的符号,因此编译器和链接器都很满意,但是启动代码将尝试调用位于“ main”位置的函数,并发现那里确实没有函数,并且崩溃。

1.)在执行main中的代码之前,将调用一个(编译器/平台)相关的函数,因此您的行为(在linux / glibc情况下为_init )。
2)第2种情况下的代码崩溃是有道理的,因为系统无法将符号main的内容作为函数来访问,而它实际上是指向任意位置的函数指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM