没有返回类型定义的main()函数会发出警告

时间:2013-08-10 04:09:13

标签: c types return main

这是我的计划:

main()
{ 
    printf("hello world\n");
}

编译时我收到此警告:

function should return a value

main()更改为void main()时,警告消失。

为什么会这样?

5 个答案:

答案 0 :(得分:8)

您应该注意以下事项:

  1. intmain()函数的返回类型。这意味着价值main()可以 return是一个整数。
  2. main( )被C90编译器所容忍,但不被C99编译器所容忍,这意味着它不再是C99标准的一部分,所以不要这样做。
  3. void main()不是标准格式,有些编译器允许这样做,但没有一个标准曾将它列为选项。因此, 编译器不必接受这种形式,有些则没有。 再次坚持标准表格, 如果将程序从一个编译器移动到另一个编译器,则不会遇到问题。
  4. 最后一件事,不是像这样写主要的:

    int main() // 在这里,您对将参数传递给main表示沉默,这意味着它可能会或可能不会参与

  5. 这样写:

    int main(void)// this specifies there are no arguments taken by main
    

    您可能需要查看 C99 standard 了解更多详情

答案 1 :(得分:7)

快速摘要:如果您不想使用命令行参数,则应编写:

int main(void) {
    /* body of main function */
}

如果你这样做:

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

这些只是 可移植方式来定义main函数。

你应该可能最后有一个return 0;,但这并不是绝对必要的。返回0表示执行成功。有办法表明执行失败;我不会在这里进入。

这背后有一些历史。有关main函数有效定义的规则在C标准的不同版本中发生了一些变化。

在1989年推出C的第一个官方标准之前,最常见的形式是:

main()
{
    /* ... */
}

或者,如果您想使用命令行参数:

main(argc, argv)
/* argc is implicitly of type int */
char *argv[];
{
    /* ... */
}

无法定义未返回值的函数。如果您未指定返回类型,则默认为int

1989 ANSI C标准(作为1990 ISO C标准的编辑更改重新发布)引入了原型,函数声明和指定参数类型的定义。 main有两个同样有效的定义。您可以使用其中一个,具体取决于您是否需要使用命令行参数:

int main(void) {
    /* ... */
}

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

char *argv[]也可以写为char **argv。此规则仅适用于参数定义。)

给定的编译器可能会也可能不会选择允许其他形式。例如,某些编译器支持第三个参数envp

不知何故,一些作者已经认识到void main()void main(void)是有效的。对于某些特定的编译器,它可以是有效的,但前提是该编译器明确支持它。它不便携。奇怪的是,首先引入void关键字的标准同时建立了main的返回类型为int的规则。

void main()非常有用,可以说明您正在阅读的图书的作者不太了解C语言,并且您应该找到另一本书。

“独立”(嵌入式)系统的故事有所不同。对于此类系统,程序的入口点完全由实现定义,甚至可能不被称为main。将其定义为void main(void)可能对此类系统有效

1999 ISO C标准删除了“隐含int”规则。首先,利用这个规则可能永远不是一个好主意。从ISO C 1990开始,您可以合法使用:

main(void) { /* ... */ }

因为它等同于:

int main(void) { /* ... */ }

自1999年标准起,int是强制性的。

1999标准还添加了一个特殊情况规则:达到}函数的结束main相当于执行return 0;。添加显式return 0;仍然是一个坏主意,特别是如果您的代码可能使用前C99编译器编译。

2011 ISO C标准未对此领域进行任何更改。

int main()int main(void)之间的区别在于后者明确表示main不带参数;前者没有指定它需要多少个参数。使用int main(void)表单。有关int main()是否合法的辩论。

你可能会忘记编写void main(),因为编译器实际上并不需要诊断它是错误的(它是未定义的行为,除非实现记录它。)

底线:main的正确定义有着悠久而多变的历史,而且你可以使用很多变体形式。但除非你是为嵌入式系统编程,否则使用除两种官方有效形式之外的任何东西都没有意义:

int main(void) { /* ... */ }

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

答案 2 :(得分:1)

c自动暗示数据类型int为没有声明数据类型的函数。因此,就编译器而言,上述内容是:

int main()
{ 
    printf("hello world\n");
}

这要求您使用return语句在结尾处返回一个整数。如果您明确地将其指定为void main(),则告诉编译器该函数没有返回值,因此没有警告。

这不是错误的原因是,如果未指定,main()将在执行结束时return 0;。但是编译器仍然会发出警告,说明这种情况正在发生。

最佳做法是在程序执行结束时使用int main()然后使用return 0

int main()
{ 
    printf("hello world\n");
    return 0;
}

有关详细信息,请参阅:this question

答案 3 :(得分:1)

您收到了警告,因为您没有指定main的返回类型。

您应始终使用int main,并返回int个号码,通常为0以获得成功。

int main()
{ 
    printf("hello world\n");
    return 0;      //you can omit this since C99
}

在托管环境中使用void main(通常我们是,如果没有,以下不一定是真的)导致未定义的行为,即使它在某些编译器中有效,从不使用它。

标准说main有两种原型,都返回int

C11 5.1.2.2.1 程序启动

  

程序启动时调用的函数名为main。实施宣布否   这个功能的原型。它应该使用返回类型int和no来定义   参数:

int main(void) { /* ... */ }
  

或有两个参数(这里称为argc和argv,但可能有任何名称   使用,因为它们是声明它们的函数的本地函数):

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

或等效的; 10)或其他一些实现定义的方式。

答案 4 :(得分:1)

return 0 ;

在最后一行。