为什么省略显式';int';参数的类型有时无法在gcc中编译?

为什么省略显式';int';参数的类型有时无法在gcc中编译?,c,gcc,C,Gcc,在C语言中声明变量时,如果要声明int,有时可以省略该类型 为什么省略参数的显式“int”类型无法在gcc中与其他非int参数一起编译,除非在K&R样式中声明 此代码生成一个错误: main(argc, char *argv[]) { /* . . . */ } 具有以下输出: $gcc XXX.c -oXXX XXX.c:X:X: error: expected ‘)’ before ‘char’ main(argc, char *argv[]) ^ 但是,如

在C语言中声明变量时,如果要声明
int
,有时可以省略该类型

为什么省略参数的显式“int”类型无法在gcc中与其他非int参数一起编译,除非在K&R样式中声明

此代码生成一个错误:

main(argc, char *argv[])
{
  /* . . . */
}
具有以下输出:

$gcc XXX.c -oXXX
XXX.c:X:X: error: expected ‘)’ before ‘char’
 main(argc, char *argv[])
            ^
但是,如果我为参数编写K&R样式类型,我可以省略为第一个参数指定
int
类型:

main(argc, argv)
char *argv[];
{
  /* . . . */
}
这很好

我怀疑原因是,在制定第一个C标准时,他们决定K&R自动int表示法应该与函数参数的较新语法完全分离,特别是因为当标准被合并时,自动int表示法可能已经被认为是糟糕的表示法


我对这些规则的兴趣是学术性的,我一般不写这种老式的C。

编译器使用两种语法中的一种

应用K&R语法时,允许使用未声明的参数,默认为int

应用非K&R语法时,所有参数必须符合参数声明语法,即使用类型和名称声明


您可以通过选择相应的声明样式来调用其中一种。C中有两种形式的函数定义:K&R样式和带有原型的现代样式。不能将它们混合在一个定义中

在K&R风格中(即Kernighan&Ritchie的《C编程语言》(the C Programming Language)1978年第一版中使用的风格,该版本在该语言的第一个官方ANSI标准发布前11年发布),您可以编写:

/* Valid in K&R and 1989 ANSI C, invalid in C99 and later */
main(argc, argv)    
char *argv[];
{
    /* . . . */
}
括号之间的内容只能是标识符序列(可能为空),即参数的名称。在
{
之间,您可以选择有一系列参数声明,指定它们的类型。如果您省略了参数或函数本身的类型,它将默认为
int

1989年的ANSI C标准保留了这一旧格式以实现向后兼容性,但宣布它已过时。(不幸的是,IMHO,即使在2011年的ISO C标准中,它仍然是这样。)

1999年的ISO C标准取消了“隐式int”规则,因此,即使出于某种奇怪的原因,您希望使用旧式定义,您仍然必须明确给出所有类型:

 /* Valid in all versions of C, but obsolescent */
int main(argc, argv)
int argc;
char *argv[];
{
    /* ... */
}
main
的现代原型定义是:

/* Valid in 1989 ANSI C and later; write it this way! */
int main(int argc, char *argv[]) { 
    /* ... */
}

您应该始终使用原型;没有很好的理由编写旧式函数定义(除非您一直在使用非常旧的编译器,但即使找到这样的编译器也变得非常困难)。

因为您不应该这样做。非常感谢,这是一个更具体的答案,其中包含一些额外有用的事实(就像在ISO99中删除隐式int一样)。正如我之前所说的,这只是学术兴趣,新的原型格式更仔细,更易于阅读,因此我对旧的格式没有任何实际用途。在第二个示例中,我是否发现了一个额外的、错误的
{