没有返回类型定义的 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】:
有几件事你应该注意:
int
是main()
函数的返回类型。这意味着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() 函数给出警告的主要内容,如果未能解决你的问题,请参考以下文章
SWIG:如何使用 %apply 返回结构? “未定义类型映射”警告