主函数必须被命名为main吗?

4
在 C 语言中,主函数能否取别的名字?“main” 这个名称是否有特殊含义,还是任意的?

1
这个问题不是建议目标的重复。这是在询问main函数的性质,而不是如何使用链接器命令覆盖它。 - Adrian Mole
2个回答

6

名称main是否有特殊含义,还是随意取的?

C程序(在托管环境中)入口点的名称“main”并非随意取的,而是由C标准定义的:

5.1.2.2.1 程序启动

1     在程序启动时调用的函数名为main。实现不声明此函数的原型。它必须定义为int类型并且没有参数:
    int main(void) { /* ... */ }
或者带两个参数(这里称为argcargv,但可以使用任何名称,因为它们只在声明它们的函数中可见):
    int main(int argc, char *argv[]) { /* ... */ }

C语言中的main函数可以以其他名称命名吗?

大多数用于编译/构建C程序的主流工具链确实提供了使用其他名称作为入口点过程的方法:通常是通过链接器选项显式指定名称,如此处所述。然而,这种程序并不严格符合C标准,并可能导致可移植性问题,如所引用的C标准草案中的“附录J”所示:

J.3 实现定义行为


J.3.2 环境

    — 在自由环境中调用程序启动时的函数的名称和类型
    — 定义main函数的另一种方式


一个必须区分C标准的一致性和严格一致性程序。使用实现定义的main()形式的程序可能是一致的,但不是严格一致的。这就是Bjarne Stroustrup和其他人混淆的地方,他们说int main(void)是唯一允许的main()形式。这只有在谈论严格符合程序时才是真的。然而,正常一致的C程序包含实现定义的行为。更改main()的名称和格式是常见的,并受到C标准的支持。 - Lundin
那么,如果一个程序没有包含“main”函数,则在编译时使用了链接器选项,将入口点过程命名为其他名称? - Yusuf
关于引用,5.1.2.2.1是“托管”子章节,所以只有一半的真相,另一半在5.1.2.1中找到。Annex J是一个信息性摘要-引用相关规范部分是从Annex J中引用的,在您的情况下是5.1.2.2.1 §3:“或以某种其他实现定义的方式”。 - Lundin
@Yusuf 不一定。一些独立系统可能默认为 void reset (void) 或类似的重置中断向量。Windows编译器可能默认为WinMain等等。重要的是编译器必须记录所有这样的实现定义行为。 - Lundin
如果我没记错的话,WinMain函数是由RTL调用的,从一个在该库中定义的名为main的函数中调用。 - Adrian Mole

4

C有两种形式的系统: freestandinghosted。Freestanding系统是没有操作系统的程序,运行在RTOS或者操作系统上。Hosted系统是指程序运行在像Linux或Windows这样的操作系统之上。

在freestanding系统中,程序启动时调用的函数名称和形式是特定于编译器的。它们可以使用int main (void)或其他完全不同的形式。最常见的是void main (void)

在hosted系统中,有两个标准化的形式存在: int main (void)int main (int argc, char* argv[])。然而,标准主观地允许实现定义的形式。

重要的是要意识到,main()或等效形式的形式始终由编译器决定,而永远不是由程序员决定的。程序员不能使用未被文档记录为有效的形式。

此外,严格符合标准的程序=无编译器特定行为,只能使用以下之一
int main (void)
int main (int argc, char* argv[]).

int main (void) 是特殊的,因为它是唯一一个可以在没有显式return的情况下返回0的函数。另外,从main()返回等价于调用exit()函数。

详见: https://dev59.com/7HVC5IYBdhLWcg3wtzkQ#31263079


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