使用新式函数声明引用尚未提及的函数参数

Referencing a yet-to-be-mentioned function parameter using the new-style function declarations

打印方阵的辅助函数被迫使用变长数组特性,我定义如下:

void print_matrix(M, dim)
     unsigned dim;
     int M[dim][dim];
{
    /* Print the matrix here. */
    ...

好消息是,代码可以正常工作,并且其参数按照我希望的顺序排列。

坏消息是,我必须使用 "old-style" 函数声明语法才能在 M 的声明中引用尚未声明的参数 dim , 这显然被认为是 obsolete and dangerous.

有没有一种直接的方法可以在不改变参数顺序的情况下对 "new-style" 函数声明做同样的事情? (如果不是,是否认为在这种特定情况下可以接受使用旧式语法?)

在可移植(标准)C 中,您不能做您显示的内容。您必须在矩阵之前指定维度。问题中的原始代码是:

void print_matrix(M, dim)
     unsigned dim;
     int (*M)[dim][dim];
{

这不能直接翻译——它需要一个像这样的原型,在矩阵之前有一个维度:

void print_matrix(unsigned dim, int (*M)[dim][dim]);

这允许您使用 3D 数组调用该函数。或者,使用问题中修改后的符号,您可以打印二维数组:

void print_matrix(unsigned dim, int M[dim][dim]);

GCC 提供了一个 extension 来协助。引用手册:

If you want to pass the array first and the length afterward, you can use a forward declaration in the parameter list—another GNU extension.

struct entry
tester (int len; char data[len][len], int len)
{
  /* … */
}

You can write any number of such parameter forward declarations in the parameter list. They can be separated by commas or semicolons, but the last one must end with a semicolon, which is followed by the “real” parameter declarations. Each forward declaration must match a “real” declaration in parameter name and data type. ISO C99 does not support parameter forward declarations.

在原型之前的旧式声明在语法上很丑陋,但并不比新式声明更危险。

void print_matrix(int M[*][*], unsigned dim);
void print_matrix(M, dim)
     unsigned dim;
     int M[dim][dim];
{
  ...
}

标准的作者认识到旧式声明是完成任务的有效、有用且充分的方法,并决定编写允许新式声明的规则工作量太大,因此他们不想打扰。因此,原型和旧式声明的组合是实现适当语义的唯一方法。