使用int main(void)编译失败,而main(int argc, char *argv[])却成功。为什么?

6

问题

如果程序不使用命令行传递的参数,为什么编译一个具有 int main(void) 主函数的程序会与编译一个具有 int main(int argc, char *argv[]) 主函数的程序不同?

这是操作系统还是编译器特定的?我使用 mingw 和 g++ 不会得到相同的结果(这很奇怪,因为 wingw 是 gcc 的一个端口)


示例

代码

#include <iostream>
#include"SDL/SDL.h"
int main(void)
{
    return 0;
}

编译命令

g++ test.cpp; #g++ 4.4.5
i586-mingw32msvc-g++ test.cpp; # mingw 4.4.4

错误

(由第二个命令提供。)

a(main.o):(.text+0x85): undefined reference to `_WinMain@16'

1
它是编译器特定的……但 int main(int argc, char *argv[]) 是“正确”的。我建议在您的所有 C 和 C++ 代码中始终使用后一种形式。 - paulsm4
@paulsm4: int main(void) 也是正确的。 - James McNellis
1
请提供一个示例程序,用于调用编译器的确切命令,编译器的确切输出以及编译器的种类和版本。没有这些信息,没有人能够明确地回答您的问题。 - James McNellis
如果您不使用 argcargv,编译 int main(int argc, char *argv[]) 将会提示未使用的参数警告,而 int main() 则不会。这是一个明显的区别。那么,您观察到了哪些其他的区别呢? - Daniel Fischer
你使用什么编译器?是哪个版本?我没有收到任何错误信息,或者你可能需要展示你的整个代码。 - Mr.Anubis
显示剩余5条评论
2个回答

11
这是关于SDL的事情。在Windows上,当你包含了SDL.h时,main会被重新定义为SDL_main,它会调用WinMain(非控制台Windows应用程序中的真正入口点),做一些初始化工作,最后调用你的主代码。 它有一个带有argcargv的签名,你基本上需要按照它的要求进行编写,所以int main()是不起作用的。

为什么它可以在g++中工作呢? - danjjl
@danjjl 因为它只在 Windows 上重新定义了。(我猜你是在其他平台上使用 g++ 进行编译) - jrok
不错 :), 你在哪里找到这些信息的?在我的例子中,即使没有真正使用SDL,这仍然是正确的吗? - danjjl
在SDL的网站的常见问题解答部分提到了这个问题,并且他们的论坛中也有很多关于此问题的帖子。 - jrok
是的,这是因为我没有链接SDL(尽管我认为不需要,因为它没有被使用)。链接SDL会出现“Undefined reference to 'SDL_main'”错误,这在FAQ中有解释。 - danjjl
“-1” 关于“非控制台 Windows 应用程序的真正入口点”是不正确的。它不是一个入口点。尽管微软对此的文档存在问题(它很臭名昭著),但控制台和 GUI 子系统应用程序的入口点没有区别。存在的区别是 Microsoft 自己链接器的默认值不同。这是一个工具问题,与 SDL 的非常恶劣的代码无关。 - Cheers and hth. - Alf

-1

main(...) 的规范是一份合同。在 C 语言中,该合同规定参数为 int 和 char **。如果您的程序希望与环境进行交互,那么它必须满足这个要求。

无论您的程序是否想使用这些参数都是另一个问题——它只需要遵守有一个名为 main 的函数,具有正确的参数顺序和类型的合同即可。


2
这个问题涉及到C++,而不是C。尽管如此,这个答案是错误的:int main(void)在C(C90、C99和C11)和C ++(C ++98、C ++03和C ++11)中都是一个完全有效的main声明。 - James McNellis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接