【问题标题】:What is meant by anonymous params? And why are they needed?匿名参数是什么意思?为什么需要它们?
【发布时间】:2020-05-04 11:09:46
【问题描述】:

我遇到过一种通知内核关于 char 设备的方法:

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

来自<linux/cdev.h> 并且不明白,怎么可能传递未命名的参数(有两个没有名字 - 第二个和第三个)。甚至,第三个参数unsigned 具有部分类型(unsigned int?char?long?...)。我在某处读过,它是为了函数重载来“选择”正确的构造函数,但如果是这样,不应该在标题中声明更多这些构造函数吗?(但没有),那么我如何引用这些参数没有名字?

【问题讨论】:

  • 这是一个函数原型。原型中的参数名称是可选的。
  • 您何时在调用函数时按名称引用参数?定义时完全是另一回事。
  • 这是一个函数原型。在代码库中搜索cdev_add,您应该会找到包含参数名称的完整函数定义。
  • “我在某处读过,它是用于函数重载以“选择”正确的构造函数” - 我认为您将 C 误认为 C++。
  • @Herdsman - 你发布的不是函数的主体。这不是函数定义,只是声明。

标签: c linux-device-driver


【解决方案1】:

这个(from here):

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

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

没有参数名称这一事实意味着参数是可选的。 C 中没有“可选参数”之类的东西,您可以通过variadic arguments 获得最接近的东西(只能在参数列表的末尾使用),但是您必须自己定义整个行为。有效的函数声明也可以指定参数名称,但这不是必需的。

这个(from here):

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

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

【讨论】:

  • C中有可选参数;用... 声明的函数可能有不同数量和类型的参数。
  • @EricPostpischil 这些不是可选参数,而是可变参数。它们可用于实现可选参数,但该语言并未为其定义任何特定语义。它们也只能用在参数列表的末尾。不过,我想提及它是有道理的。
  • 还是不明白类型unsigned那是什么类型? unsigned 可以是 char、int、long、...,几乎 c 中的每种类型都可以是 unsigned(非负数)。所以它是部分类型,而不是完整类型。这怎么可能?
  • unsigned 是写unsigned int 的更短的方式。 long 也是如此,即 long intlong longsignedshort。见here
【解决方案2】:

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

  • 首先是它们不需要在函数原型中使用,因为原型的唯一目的是告知编译器要在调用中使用的参数数量和类型。为了检查两个原型是否兼容(相同类型),您只需检查参数顺序和每个参数的类型,而不是名称,因此如果您放置没有参数名称的原型,您可以轻松检查功能的兼容性。参数仅在函数实现中需要,因此在原型中可以避免使用。我个人不建议这样做,因为参数名称通常会在其名称中包含一些关于其用途的文档(即使它不被使用,你可以称之为dumbunused,见下文),所以通过对原型的单一视图,您可以猜出它的用途。
  • 第二个更详细,可以避免命名未使用的参数(C 不允许在实现中使用未命名参数,仅在原型中使用,而 C++ 在实现中使用未命名参数表示未使用参数, 但函数接口要求——调用者必须提供一个值需要使用这些参数中的一个或多个。如果您命名未使用的参数,您可能会在声明以后不使用的参数时收到编译器警告。更糟糕的是,如果你命名它,并且无意中在函数中使用它,你会得到有效的代码但是错误的(因为那个参数没有被使用)所以最好得到一个关于一些未声明变量的错误,如果你尝试使用它。但这是 C++ 的东西,问题被标记为 C,所以我不会对此进行更多扩展。

【讨论】:

    猜你喜欢
    • 2013-05-10
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 2016-11-29
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    相关资源
    最近更新 更多