Что подразумевается под анонимными параметрами? И зачем они нужны? - PullRequest
0 голосов
/ 04 мая 2020

Я столкнулся с методом уведомления ядра об устройстве устройства:

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

из <linux/cdev.h> и не понимаю, как можно передавать безымянные параметры (есть два без имени - второе и третье ). И даже, третий аргумент unsigned имеет частичный тип (unsigned int? Char? Long? ...). Я где-то читал, это для перегрузки функций, чтобы "выбрать" правильный конструктор, но если это так, не должно быть объявлено больше этих конструкторов в заголовке? (Но это не так), так как я могу ссылаться на такие параметры без имен?

Ответы [ 2 ]

3 голосов
/ 04 мая 2020

Это ( отсюда ):

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

Является ли функция декларацией . Он определяет тип трех параметров, которые принимает функция, и тип возвращаемого значения: в этом случае функция возвращает int и принимает в качестве параметров a struct cdev *, dev_t и unsigned. Обычно это делается в заголовочных файлах (.h), которые позже включаются, чтобы дать компилятору знать, какие типы обрабатываются и возвращаются функцией.

Тот факт, что имена параметров отсутствуют, не означает, что параметры являются необязательными. В C нет такого понятия, как «необязательный параметр», ближайший вы можете получить через variadi c arguments (который можно использовать только в конце списка параметров), но вы Придется определять все поведение самостоятельно. Допустимое объявление функции также может указывать имена параметров, но это не обязательно.

Это ( отсюда ):

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

Является ли функция определением . Он должен определять все имена параметров и тело функции, содержащие фактический код.

2 голосов
/ 06 мая 2020

Анонимные (неназванные) параметры имеют две цели:

  • Во-первых, их не нужно использовать в прототипах функций, поскольку единственная цель прототипа - сообщить компилятору о количество параметров и их типы для вызова. Чтобы проверить совместимость двух прототипов (одного и того же типа), вы должны проверить только порядок параметров и типы каждого параметра, но не имена, поэтому, если вы поместите прототипы без имен параметров, вы можете легко проверить совместимость функций. Параметры нужны только при реализации функции, поэтому их можно избежать в прототипе. Лично я не рекомендую это, поскольку имя параметра обычно содержит некоторую документацию о его назначении (даже если оно не используется, так как вы можете назвать его dumb или unused, см. Ниже), поэтому с помощью одного представления к прототипу вы можете угадать, для чего он используется.
  • Второй более сложный, вы можете избежать именования неиспользуемых параметров (C не позволяет использовать безымянные параметры в реализация, только в прототипах, в то время как C ++ использует безымянные параметры в реализациях, чтобы сигнализировать, что параметры не используются, но требуются интерфейсом функции - вызывающая сторона должна предоставить значение) В C ++ ситуация другая: дело в том, что Предположим, вам нужно реализовать некоторую функцию, которая должна реализовывать интерфейс с префиксом, но реализация не должна использовать один или несколько из этих параметров. Если вы назовете неиспользуемый параметр, вы, вероятно, получите предупреждение компилятора при объявлении параметра, который позже вы не используете. Хуже того, если вы назовете его и случайно используете его внутри функции, вы получите правильный код, но ошибочный (так как этот параметр не должен был использоваться), поэтому было бы лучше получить ошибку о некоторой необъявленной переменной, если вы попробуйте использовать это. Но это все, что связано с C ++, и вопрос был помечен C, поэтому я не буду более подробно останавливаться на этом.
...