我去了一个在线编译C语言的网站,看到main
函数声明没有返回类型。
我知道这里有一些关于这个主题的问题,但是我没有发现任何关于省略返回类型的问题。我试着用gcc编译代码,它工作了。
这是否意味着如果我们没有在main
上放置返回类型,它将假设它是int(或任何其他类型)?
C89标准,为了保持与没有函数原型的原始C &R版本的兼容性,允许函数隐式返回int
。任何未声明显式返回类型的函数(如void
、float
等)都被编译器假定返回int
。
main
函数时没有返回类型,则假定它返回类型为int
。一切都很好,因为根据标准,main
应该返回int
。
然而,这在C99中改变了。默认/隐式int
规则已从语言规范中删除。没有显式返回类型的函数不再被假定返回int
。
这意味着对于任何现代编译器,遵循当前版本的C语言规范,没有返回类型的main
声明是无效的。
至于为什么它在GCC上工作,这是因为默认情况下,GCC仍然遵循C89/C90标准,除非您显式指定-std=c99
作为编译器标志。至于为什么你还能在网上看到这个,有两个原因。第一个是我已经给出的:它在语言规范的旧版本中是合法的,并且许多旧代码没有更新。第二个原因是,不幸的是,网上和书中有很多糟糕的 C代码。
尝试打开警告,GCC会告诉您这通常是被禁止的:
test.c:1:1: warning: return type defaults to ‘int’ [-Wreturn-type]
main()
^
在旧的C语言中有一个定义的含义,在旧的C语言中函数的默认类型是int
。编译器仍然支持它,为了不破坏代码,因为它不是一个大问题,即代码不会突然含糊不清。
如果在C89中省略返回类型,则假定该函数返回类型为int
的值。在C99/11中,省略函数的返回类型是不合法的。main
的签名定义为:
C11 5.1.2.2.1程序启动:
1程序启动时调用的函数命名为
main
。实现声明no这个函数的原型。它应该定义为返回类型int
,并带有no参数:int main(void) { /* ... */ }
或两个参数(这里称为
argc
和argv
,尽管任何名称都可以)使用时,因为它们是声明它们的函数的局部):int main(int argc, char *argv[]) { /* ... */ }
或等价的;10)或以其他实现定义的方式。
编译带有-std=c99
标志的代码,编译器将对省略的返回类型发出警告。