匿名参数是什么意思?为什么需要它们?

What is meant by anonymous params? And why are they needed?

我遇到了一种通知内核有关字符设备的方法:

int cdev_add(struct cdev *, dev_t, unsigned);

来自 <linux/cdev.h> 并且不明白,如何传递未命名的参数(有两个没有名称 - 第二个和第三个)。甚至,第三个参数 unsigned 具有部分类型(unsigned int?char?long?...)。我在某处读过,它是为了函数重载到 "pick" 正确的构造函数,但如果是这样,不应该在 header 中声明更多这些构造函数?(但没有),所以我如何引用没有名称的此类参数?

这个(from here):

int cdev_add(struct cdev *, dev_t, unsigned);

是函数声明。它指定函数接受的三个参数的类型和 return 类型:在这种情况下,函数 returns 是一个 int,并接受一个 struct cdev * 作为参数,一个 dev_t 和一个 unsigned。这通常在头文件 (.h) 中完成,稍后包含这些文件是为了让编译器知道函数处理和 return 哪些类型。

没有参数名称的事实 而不是 意味着参数是可选的。 C中没有"optional parameter"这样的东西,最接近的是通过variadic arguments(只能用在参数列表的末尾),但你必须定义整个自己的行为。有效的函数声明还可以指定参数名称,但这不是必需的。

这个(from here):

int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
    // ... body skipped for simplicity ...
    return 0;
}

是函数定义。它必须定义所有参数名称和函数体,包含实际代码。

匿名(未命名)参数有两个用途:

  • 首先是它们不需要在函数原型中使用,因为原型的唯一目的是通知编译器调用中要使用的参数数量和类型。为了检查两个原型是否兼容(相同类型),你只需要检查参数顺序和每个参数的类型,而不是名称,所以如果你放置没有参数名称的原型,你可以很容易地检查功能的兼容性。参数只在函数实现时需要,所以在原型中可以避免。我个人不推荐这样做,因为参数名称通常在其名称中有一些关于其用途的文档(即使它不被使用,你可以称它为 dumbunused,请参阅下方),因此只需查看原型,您就可以猜出它的用途。
  • 第二种更精细,可以避免命名未使用的参数(C 不允许在实现中使用未命名参数,只能在原型中使用,而 C++ 在实现中使用未命名参数来表示参数是未使用,但函数接口需要——调用者必须提供一个值)在 C++ 中情况不同:问题是,假设你必须实现一些必须实现前缀接口的函数,但实现没有' 需要使用这些参数中的一个或多个。如果您命名未使用的参数,您可能会在声明稍后不使用的参数时收到编译器警告。更糟糕的是,如果你给它命名,并且无意中在函数内部使用它,你会得到有效但错误的代码(因为那个参数没有被使用)所以最好得到一些关于一些未声明变量的错误,如果你尝试使用它。但这是 C++ 的东西,问题被标记为 C,所以我不会对其进行更多扩展。