C++ 中 main 的正确声明是什么?[复制]

What is the proper declaration of main in C++? [duplicate]

提问人:fredoverflow 提问时间:11/18/2010 最后编辑:Jan Schultkefredoverflow 更新时间:9/26/2023 访问量:122548

问:

问题

  • C++ 中函数的正确签名是什么?main

  • 什么是正确的返回类型,从中返回值意味着什么?main

  • 允许的参数类型是什么,它们的含义是什么?

  • 这是特定于系统的吗?

  • 这些规则是否随时间而改变?

  • 如果我违反它们会怎样?

C 函数 语言-律师 程序-入口C ++-FAQ

评论

0赞 fredoverflow 5/18/2014
@JonathanLeffler 别开玩笑了......大约 8 个月前,它被添加到修订版 6 的重复列表中。
0赞 Jan Schultke 9/26/2023
这个问题不是 在 C 和 C++ 中应该返回什么 main() 的精确重复?。然而,它所问的一切已经在那里得到了更详细、更高质量的回答,这使得这个问题重复出现。这个问题在目前的状态下也是有问题的,因为它不是很专注,并且询问系统细节、历史变化和各种事情,只是为了有力地区分自己。这本身就可能值得一个“需要关注”的密切理由。

答:

206赞 James McNellis 11/18/2010 #1

该函数必须在全局命名空间中声明为非成员函数。这意味着它不能是类的静态或非静态成员函数,也不能放在命名空间(甚至是未命名的命名空间)中。main

该名称在 C++ 中不保留,但作为全局命名空间中的函数除外。您可以自由声明其他命名的实体,其中包括类、变量、枚举、成员函数和非成员函数等不在全局命名空间中。mainmain

可以将名为成员函数或命名空间中的函数声明为函数,但此类函数不是指定程序启动位置的函数。mainmain

该函数不能声明为 或 。它也不能超载;全局命名空间中只能有一个函数命名。mainstaticinlinemain

该函数不能在程序中使用:不允许从代码中的任何位置调用该函数,也不允许获取其地址。mainmain

main 的返回类型必须为 int。不允许使用其他返回类型(此规则以粗体显示,因为经常会看到不正确的程序声明返回类型为 ;这可能是有关函数的最常违反的规则)。mainvoidmain

必须允许以下两个声明:main

int main()               // (1)
int main(int, char*[])   // (2)

在(1)中,没有参数。

在(2)中,有两个参数,它们分别被约定为和。 是指向表示程序参数的 C 字符串数组的指针。 是数组中的参数数。argcargvargvargcargv

通常,包含程序的名称,但情况并非总是如此。 保证为 null 指针。argv[0]argv[argc]

请注意,由于数组类型参数 (like ) 实际上只是一个伪装的指针类型参数,因此以下两种都是有效的写法 (2),它们的含义完全相同:char*[]

int main(int argc, char* argv[])
int main(int argc, char** argv)

某些实现可能允许其他类型和数量的参数;您必须查看实现的文档才能了解它支持的内容。

main()预计返回零表示成功,返回非零表示失败。你不需要显式地写一个语句:如果你让return没有显式的语句,它和你写的是一样的。以下两个函数具有相同的行为:returnmain()main()returnreturn 0;main()

int main() { }
int main() { return 0; }

中定义了两个宏 和 ,也可以从中分别返回以指示成功和失败。EXIT_SUCCESSEXIT_FAILURE<cstdlib>main()

返回的值将传递给函数,该函数将终止程序。main()exit()

请注意,所有这些内容仅在为托管环境(非正式地,您拥有完整的标准库并且运行程序的操作系统的环境)进行编译时才适用。也可以为独立环境(例如,某些类型的嵌入式系统)编译 C++ 程序,在这种情况下,启动和终止完全由实现定义,甚至可能不需要函数。但是,如果您正在为现代桌面操作系统编写 C++,那么您正在为托管环境进行编译。main()

评论

1赞 Derrick Turk 11/18/2010
IIRC 唯一保证的返回值是 0、EXIT_SUCCESS(与 0 的效果相同)和 EXIT_FAILURE。编辑:啊,好的,可能会返回其他非零状态值,但具有实现定义的含义。只有EXIT_FAILURE才能保证以某种方式解释为故障值。
4赞 James McNellis 12/22/2010
@Synetech:问题在第一句话中问道,“C++中主函数的正确签名是什么?”,并且问题被标记为 [c++] 和 [c++-faq]。如果 Java 或 C# 用户(或其他任何人)仍然感到困惑,我无能为力。C# 要求是静态成员函数,因为它甚至没有非成员函数。甚至 C89 也需要返回.我对 K&R C 不够熟悉,不知道它的确切规则,但我猜它也需要返回,因为 with no return 类型有些常见,并且 K&R 中没有类型 = 隐含。Mainmainintmainintmainint
3赞 James McNellis 6/16/2011
@Suhail:因为语言标准规定返回类型应为 .int
1赞 James McNellis 6/16/2011
@Suhail:是的。你的代码不会是正确的 C++,许多编译器会拒绝你的代码。
3赞 James McNellis 6/16/2011
@Suhail:Visual C++允许将返回类型作为语言扩展。不允许它的编译器包括 GCC 和 Comeau。void
3赞 stonemetal 11/18/2010 #2

两个有效的电源是 和 。其他任何事情都可能编译,也可能不编译。如果未显式返回值,则隐式返回 0int main()int main(int, char*[])main

评论

1赞 Suhail Gupta 6/15/2011
当我提到 to be void 的返回类型时,我从未见过代码没有被编译。main 的返回类型应该是 int 有什么具体原因吗?main
4赞 stonemetal 6/16/2011
语言规范规定 main 必须具有 int 的返回类型。编译器允许的任何其他返回类型都是特定于编译器的增强功能。基本上,使用 void 意味着您正在使用类似于 C++ 的语言进行编程,但并非如此。
2赞 uckelman 7/12/2013
该标准要求 an 作为 的返回类型的原因在于,此值作为程序的退出代码传递给 shell,并期望 .intmainshint
0赞 Andreas Spindler 10/30/2018
也许原因是纪律?可以有不止一条出路。如果返回类型为 ,则它们都是静默的。我们必须为 的每个返回值定义特定的退出值。voidintmain
15赞 liaK 11/18/2010 #3

来自标准文档,3.6.1.2 Main 函数

它应该有回报 int 类型的 type,否则其类型是实现定义的。所有实现都应允许以下两项 main的定义:

int main() { / ... / }int main(int argc, char* argv[]) { / ... / }

在后一种形式中,应是从环境传递给程序的参数数,其中 程序运行。如果 argc 为非零,则这些参数应在 argv[0] 到 argv[argc-1] 中作为指向 以 null 结尾的多字节字符串的初始字符.....argc

希望能有所帮助..

评论

2赞 Suhail Gupta 6/15/2011
是否有任何具体原因说明为什么返回类型应该是?mainint
1赞 Lightness Races in Orbit 1/2/2017
@SuhailGupta:以便调用进程知道过程是否应被视为成功。允许打破这种模式。如果你把它的意思是“总是认为成功”,这甚至没有意义。因为你没有办法说这个过程是否真的失败了,所以你真的成功了吗?不,返回.voidint
2赞 Ben Voigt 1/2/2012 #4

有关返回值及其含义的详细信息

每 3.6.1 ():[basic.start.main]

中的 return 语句具有离开函数(销毁任何具有自动存储持续时间的对象)并使用返回值作为参数进行调用的效果。如果控制到达 的末尾而没有遇到语句,则效果是执行mainmainstd::exitmainreturn

return 0;

的行为在第 18.5 节 () 中进行了详细说明,并描述了状态代码:std::exit[support.start.term]

最后,将控制权交还给主机环境。如果 status 为 0 或 ,则返回状态成功终止的实现定义形式。如果 status 为 ,则返回状态 unsuccessful terminateation 的实现定义形式。否则,返回的状态为实现定义的状态。EXIT_SUCCESSEXIT_FAILURE

3赞 M.M 7/1/2017 #5

最新发布的标准(C++14)的确切措辞是:

实现应允许两者

  • 返回和()int

  • 的函数 ,指针到指针的返回(intchar)int

作为 的类型。main

这清楚地表明,只要 的类型是 type 或 .因此,以下情况也是允许的:mainint()int(int, char**)

  • int main(void)
  • auto main() -> int
  • int main ( )
  • signed int main()
  • typedef char **a; typedef int b, e; e main(b d, a c)

评论

1赞 M.M 7/1/2017
铌。我在另一个线程的评论中发布了这个答案,有人试图引用这个线程作为 C++ 中不正确的证据。int main(void)
4赞 7/1/2017
@Stargateur没有推导的返回类型。注意 “(auto main() {...是不允许的)“,当你还没有足够的知识来添加任何有意义的东西时,请学会知道。auto main() -> int
0赞 GoldBishop 12/12/2023
子弹 #5 让我笑了起来......让我想起了我编程的 DIKUMUD 时代。TypeDef 一个 TypeDef 来定义 TypeDef ;)