main的正确声明是什么?


147

mainC ++中函数的正确签名是什么?正确的返回类型是什么,从中返回值是什么意思main?允许的参数类型是什么,它们的含义是什么?

这是特定于系统的吗?这些规则是否随着时间而改变?如果我违反了该怎么办?


1
这与C和C ++ 应该main返回什么紧密相关或重复。
乔纳森·勒夫勒

@JonathanLeffler没开玩笑... 大约8个月前,它已添加到修订版6的重复列表中。
fredoverflow

Answers:


192

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

该名称main在C ++中没有保留,只能作为全局名称空间中的函数使用。您可以自由声明其他名为的实体main,其中包括类,变量,枚举,成员函数和不在全局命名空间中的非成员函数。

您可以将函数声明main为成员函数或在命名空间中声明,但是这样的函数将不是main指定程序在何处启动的函数。

main函数不能声明为staticinline。它也不能过载。main全局名称空间中只能有一个命名的函数。

main函数不能在您的程序中使用:不允许main在代码中的任何地方调用该函数,也不允许使用其地址。

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

main必须允许有两个声明:

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

(1)中,没有参数。

(2)中,有两个参数,它们分别按常规命名为argcargvargv是指向表示程序参数的C字符串数组的指针。argcargv数组中参数的数量。

通常,argv[0]包含程序的名称,但并非总是如此。 argv[argc]保证是一个空指针。

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

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

一些实现可以允许其他类型和数量的参数。您必须查看实施文档以了解其支持的内容。

main()预期返回零表示成功,返回非零表示失败。您无需在中显式编写return语句main():如果main()不使用显式return语句就让return ,则与您编写的相同return 0;。以下两个main()函数具有相同的行为:

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

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

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

请注意,所有这些仅适用于针对托管环境(非正式地,您具有完整的标准库并且有一个操作系统正在运行您的程序的环境)进行编译的情况。还可以针对独立环境(例如某些类型的嵌入式系统)编译C ++程序,在这种情况下,启动和终止完全由实现定义,并且main()甚至可能不需要功能。但是,如果您要为现代台式机操作系统编写C ++,则需要针对托管环境进行编译。


1
IIRC唯一保证的返回值是0,EXIT_SUCCESS(效果与0相同)和EXIT_FAILURE。编辑:嗯,好的,可能会返回其他非零状态值,但是具有实现定义的含义。只能保证以某种方式将EXIT_FAILURE解释为失败值。
德里克·特克

4
@Synetech:问题的第一句话是:“ C ++中主要函数的正确签名是什么?” 问题被同时标记为[c ++]和[c ++-faq]。如果Java或C#用户(或其他任何人)仍然感到困惑,我无能为力。C#必须Main是静态成员函数,因为它甚至没有非成员函数。甚至C89也需要main返回int。我对K&R C不够熟悉,无法知道其确切规则,但是我猜想它也需要main返回,int因为在K&R中main没有返回类型是很常见的,并且没有类型=隐式int
James McNellis

3
@Suhail:因为语言标准说返回类型应该是int
James McNellis 2011年

1
@Suhail:是的。您的代码不是正确的C ++,许多编译器都会拒绝您的代码。
James McNellis 2011年

2
@Suhail:Visual C ++允许将void返回类型作为语言扩展。不允许使用的编译器包括GCC和Comeau。
James McNellis 2011年

15

根据标准文档3.6.1.2主要功能

它的返回类型应该是int类型,否则它的类型是实现定义的。所有实现均应允许以下两个main定义:

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

在后一种形式中,argc为从运行程序的环境传递到程序的参数数量。如果argc不为零,则这些参数应以argv [0]至argv [argc-1]的形式提供给初始参数。空终止的多字节字符串的字符 .....

希望有帮助。


2
是否有任何特定原因说明为什么的返回类型main应为int
Suhail Gupta

1
@SuhailGupta:以便调用过程知道过程是否应该被视为成功。允许void破坏该模型。如果您的意思是“总是认为成功”,那甚至没有任何意义。因为您无法说出过程是否真的失败,所以您真的成功了吗?不,返回int
Lightness Races in Orbit

4

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

一个实现应允许两个

  • 函数()返回int

  • 的功能(int,指向char)返回指针的指针int

作为的类型main

这清楚表明,只要的类型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
注意 我在另一个线程的注释中发布了此答案,有人试图引用此线程作为int main(void)在C ++中不正确的证据。
MM

3
@Stargateur auto main() -> int没有推断的返回类型。请注意“((auto main(){... is not allowed))”中的{,并请了解何时尚不足够添加任何有意义的内容。

3

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


1
当我提到返回类型为mainvoid 时,我从未见过代码没有被编译。main的返回类型应为int的原因是什么?
Suhail Gupta

4
语言规范说main必须具有int的返回类型。编译器允许的任何其他返回类型是特定于编译器的增强功能。基本上使用void意味着您正在使用类似于但不类似于C ++的语言进行编程。
stonemetal 2011年

2
该标准要求使用intas作为返回类型的原因main是,该值作为程序的退出代码传递给shell,并sh期望使用int
uckelman

也许原因是纪律?可能有不止一条路。如果返回类型是,则void它们都保持沉默。使用,int我们必须为的每个返回定义特定的退出值main
安德里亚斯·斯平德勒

2

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

按照3.6.1([basic.start.main]):

in main中的return语句的作用是保留main函数(使用自动存储持续时间销毁所有对象)并std::exit使用返回值作为参数进行调用。如果控制在main没有遇到return语句的情况下到达末尾,则效果是执行

return 0;

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

最后,控制权返回到主机环境。如果status为零或EXIT_SUCCESS,则返回实现定义的状态成功终止的形式。如果status为EXIT_FAILURE,则返回实现定义的状态,表示状态失败终止。否则,返回的状态是实现定义的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.