No.
根据标准的规范性措辞,定义
使用空括号而不使用void
关键字不是其中之一
必须接受的形式,严格来说,行为
这样的程序是未定义的。
参考:N1570 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf第 5.1.2.2.1 节。 (2011 年发布的 ISO C 标准,未
免费提供,措辞与 N1570 草案相同。)
第 1 段说:
程序启动时调用的函数名为main
。实施声明没有
该函数的原型。它的返回类型应定义为int
并且没有
参数:
int main(void) { /* ... */ }
或带有两个参数(此处称为argc
and argv
,尽管任何名称都可以是
使用,因为它们对于声明它们的函数来说是本地的):
int main(int argc, char *argv[]) { /* ... */ }
或同等学历;或者以其他一些实现定义的方式。
在约束之外使用“应”一词意味着任何
违反它的程序具有未定义的行为。例如,如果我写:
double main(unsigned long ocelots) { return ocelots / 3.14159; }
不需要符合标准的编译器来打印诊断信息,但它是
也不需要编译程序,或者如果确实编译了
它,让它以任何特定的方式表现。
If int main()
were 相等的 to int main(void)
,那么它
对于任何符合要求的托管实现都是有效且可移植的。
但这并不等同。
int main(void) { }
提供了两个宣言(在本例中为原型)和定义。该声明通过使用void
关键字,指定该函数没有参数。该定义指定了同样的事情。
如果我改为写:
int main() { }
然后我用的是老式声明和定义。 (这样的
声明和定义是过时的,但他们仍然
语言定义的一部分,所有符合标准的编译器必须
还是支持他们。)
作为声明,它不指定参数的数量或类型
函数所期望的。作为定义,它没有定义任何参数,
但编译器不需要使用该信息来诊断不正确的调用。
DR #317 http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_317.htm包括 C 标准委员会 2006 年的裁决:()
不提供与以下原型相当的原型(void)
(感谢 hvd 找到该参考资料)。
C允许main
被递归调用。假设我写:
int main(void) {
if (0) {
main(42);
}
}
可见的原型int main(void)
指定main
需要
没有争论。尝试传递一个或多个参数的调用
违反约束,需要编译时诊断。
或者假设我写:
int main() {
if (0) {
main(42);
}
}
如果打电话main(42)
被执行,它会有未定义的行为
——但它不违反约束,并且不需要诊断。
由于它受到保护if (0)
,呼叫永远不会发生,并且
未定义的行为实际上从未发生。如果我们假设int main()
是有效的,那么这个程序必须被任何人接受
符合编译器。但也正因为如此,才表明int main()
is not相当于int main(void)
,因此
5.1.2.2.1 未涵盖。
结论:按照标准的措辞,
允许实施以记录int main() { }
是
允许的。如果没有记录,仍然可以接受
毫无怨言。但符合标准的编译器也可能reject
int main() { }
,因为它不是 允许的形式之一
标准,因此其行为是未定义的。
但仍然有一个悬而未决的问题:这是作者的意图吗?
标准的?
在 1989 年 ANSI C 标准发布之前,void
关键字不存在。 Pre-ANSI (K&R) C 程序将定义main
要么作为
main()
or as
int main()
ANSI 标准的一个主要目标是添加新功能(包括
原型)without破坏现有的 ANSI 之前的代码。说明int main()
不再有效就会违反该目标。
我怀疑 C 标准的作者没有intend使int main()
无效的。但书面标准并没有
反映该意图;至少它permits符合标准的 C 编译器
拒绝int main()
.
几乎说起来,你几乎肯定可以逃脱惩罚。
我尝试过的每个 C 编译器都会接受
int main() { return 0; }
没有抱怨,行为相当于
int main(void) { return 0; }
但由于多种原因:
- 遵循标准的文字和意图;
- 避免使用过时的功能(未来的标准可能会删除旧式的函数定义);
- 保持良好的编码习惯(之间的区别
()
and (void)
对于除此之外的功能很重要main
实际上是由其他函数调用的)。
我建议总是写int main(void)
而不是int main()
。
它更清楚地表达了意图,您可以 100% 确定您的
编译器会接受它,而不是 99.9%。