4

我在C 编译器的早期源代码中发现了以下声明代码

main(argc, argv)
int argv[]; { 
   return 0;
}

我尝试在 ideone.com 上运行它,使用 gcc-4.7.2 以“C”模式编译它,它编译得很好,甚至运行成功

result: Success     time: 0s    memory: 1828 kB     returned value: 0

现在我知道有一种预先标准的方式来声明函数参数:

int funct(crc, buf, len)
    int crc;
    register char* buf;
    int len;
{
   //function implementation
}

但在后一种风格中,它很清楚——首先列出参数,然后将它们声明为一种局部变量,我看到所有声明的参数和返回类型。

回到第一个代码

main(argc, argv)
int argv[]; { 
   return 0;
}

在之前的代码中,列出了两个参数,并且只声明了一个参数,并且看起来像argv具有 type array of int

编译器如何处理它?

4

4 回答 4

1

这是 K&R C 语法,编译器不会检查参数的类型,参数将默认为 int。

K&R sysntax 仍然得到最新编译器的支持以实现兼容性。在代码必须由符合标准或基于 K&R C 的编译器编译的情况下,STDC宏可用于将代码拆分为标准和 K&R 部分以防止使用仅在标准 C 中可用的基于 K&R C 的功能编译器。

于 2013-05-22T07:34:11.767 回答
1
main(argc, argv)
int argv[]; { 
   return 0;
}
  1. 由于隐式整数转换规则,类型argcintK&R C 和 C90 中,但它不是 C99 和 C11 中的一致代码。因为隐式 int 转换在 C99 和 C11 中已被弃用。main() 的返回值也是如此。

  2. main() 接收从主机传递的参数。由于 main() 不能接收数组,ints而只能接收字符串数组。这可能会导致未定义的行为,因为无法使用整数数组访问传递给 main() 的实际参数。编译器无法对参数进行类型检查,因为 main() 是从外部(从托管环境)调用的。所以编译器假定你所说的 main() 参数是正确的。你甚至可以这样做:

int main(argc, argv, a, b,c)
int argc;
int argv[];
int a, b, c;
{
....
}

这是一个有效的代码。但是没有合法的方法可以访问所有这些ints(argc 除外)。

于 2013-05-22T07:48:44.903 回答
1

您说的是 ANSI C 之前的版本,以及称为 K&R 原型的原型风格。对于此类函数声明,未指定类型的参数和返回值被视为类型int

于 2013-05-22T07:18:56.620 回答
0

GCC 默认带有非标准设置。您发布的代码不会在符合标准的 C 编译器上编译。

改为使用 C 编译器进行编译。gcc -std=c99 -pedantic-errors不会编译你的代码。

于 2013-05-22T07:31:38.453 回答