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

Posted

技术标签:

【中文标题】没有返回类型定义的 main() 函数给出警告【英文标题】:main() function defined without return type gives warning 【发布时间】:2013-08-12 02:02:47 【问题描述】:

这是我的程序:

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

编译时收到此警告:

function should return a value

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

为什么会这样?

【问题讨论】:

这是你可以通过简单的搜索找到的东西here 应该是int main(void) 【参考方案1】:

return 0 ;

在最后一行。

【讨论】:

请在您的回答中添加更多描述【参考方案2】:

快速总结:如果你不想使用命令行参数,你应该写:

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[])  /* ... */ 

【讨论】:

从所有这些演变中幸存下来的人提供了相当广泛的答案......这个更简单的替代方案好吗:int main() /* ... */ @chqrlie:取决于你如何定义“OK”。 int main() 不是原型,根据 C 标准,非原型函数声明和定义是“过时的”。我认为任何 C 编译器都会接受int main() /* ... */ ,我相信标准作者的意图是它应该是可以接受的,但标准实际上并没有说它是。我在这里详细讨论过这个问题:Is int main() necessarily valid? Should it be?.【参考方案3】:

有几件事你应该注意:

    intmain() 函数的返回类型。这意味着main()的那种值可以 return 是一个整数。 main( ) 被 C90 编译器允许,但 C99 编译器不允许,这意味着它不再是 C99 标准的一部分,所以不要这样做。 void main() 不是标准形式,一些编译器允许这样做,但没有一个标准将其列为选项。所以, 编译器不必接受这种形式,有些则不需要。 再次,坚持标准形式, 如果您将程序从一个编译器移到另一个编译器,您也不会遇到问题。

    最后一件事,而不是像这样写 main :

    int main() // 在这里你对向 main 传递参数保持沉默,这意味着它可能会或可能不会接受参数

这样写:

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

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

【讨论】:

第 4 点是错误的。作为定义,int main() ... int main(void) ... 相同。仅作为声明(即int main();),没有void 的表单未指定参数。 @R..:函数定义包含声明。 int main() 可能会被任何现有编译器接受,但您仍应使用 int main(void)。我已经进一步讨论了这个here。【参考方案4】:

您收到警告是因为您没有指定 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 并且没有 参数:

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

或带有两个参数(此处称为 argc 和 argv,尽管任何名称都可以 使用,因为它们在声明它们的函数中是本地的):

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

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

【讨论】:

其实K&R C第一版并没有在hello world例子中指定main()的类型。 @Wyatt8740 这是因为 K&R C 第 1 版。 早于 ANSI/ISO C (C89/90)。在 K&R 和 C89/90 中,有一条“隐式 int”规则,该规则规定省略返回类型的函数会自动被视为返回 int。 C99 放弃了这条规则,因此在 K&R 和 C89/90 中不为 main() 指定返回类型很好,但现在情况并非如此,老实说,除非你处于 ANSI/ISO C 之前的环境中,否则你真的应该永远不要使用隐式 int 规则。 (看看 Keith Thompson 的回答 here。) 是的,@RastaJedi - 我知道它早于 ANSI。我想基本上每个人都知道这一点。 @Wyatt8740 实际上有很多人因为第二版而混淆了“K&R”这个绰号。的书。有趣的是,他们在该示例中没有使用返回类型,+1。 @RastaJedi 名字“C89”(阅读:1989)和最初的第一版出版日期会告诉我。【参考方案5】:

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 了解更多信息。

【讨论】:

不,void main 无效,始终使用int main 1999 ISO C 标准删除了“隐式 int”规则,使 main() 无效。

以上是关于没有返回类型定义的 main() 函数给出警告的主要内容,如果未能解决你的问题,请参考以下文章

为啥写作主要;在 C 中给出一个段错误

SWIG:如何使用 %apply 返回结构? “未定义类型映射”警告

void main(), int main() 和int main(void)的区别

main函数的返回类型有啥区别

C语言中函数可以返回哪些类型的数据?(求详解)

请问C++中如果需要中途退出程序,exit(1)和exit(0)以及return有啥区别呢? 谢谢!