Зачем приводить неиспользуемое значение параметра функции к void?

98

В каком-то проекте C я видел этот код:

static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
    (void)ud;
    (void)osize;
    /* some code not using `ud` or `osize` */
    return ptr;
}

Служат ли два слепка на аннулирование какой-либо цели?

Bastibe
источник
Голосование за закрытие, поскольку правильный ответ (запрещение предупреждений компилятора о неиспользуемых параметрах) находится в связанном вопросе Чарльза.
TED
@Cody Gray - По этой причине он был закрыт. Однако на самом деле это не было дублированием этого вопроса. 689677 говорил о возвращении литья в пустоту, а не о параметрах.
TED
19
На самом деле оба дубликата не подходят для этого вопроса. Один - это C ++, другой - о возвращаемых значениях. Это не одно и то же . Есть ли дубликаты параметра C?
Мэтт Джойнер
2
Это другой вопрос, чем предложенные дубликаты. Но я понимаю, почему была допущена ошибка. Повторно открыли (очевидно).
Тим Пост
4
Примечание: пожалуйста, не закрывайте это как дубликат вопроса C ++, поскольку C ++ использует (void)несколько иной эффект. Этот вопрос о C
Антти Хаапала

Ответы:

89

Это нужно, чтобы избежать предупреждений от компилятора, потому что некоторые параметры не используются.

Бенуа Тьери
источник
3
Как лучше всего подавить предупреждения: stackoverflow.com/questions/3417837/…
Ciro Santilli 郝海东 冠状 病 六四 事件
@Benoit, что на самом деле делает приведение к void? Это единственная функция - показать компилятору, что вы намеренно что-то игнорируете или (void) действительно что-то делает, и когда компилятор это видит, он просто считает это как сделавшее что-то с переменной и, следовательно, не выдает предупреждение?
Тан Ван
2
@TanWang Его единственная функция - показать компилятору, что вы намеренно что-то игнорируете. Во время выполнения он ничего делать не будет.
zwol
14

Причина наличия неиспользуемых параметров в прототипе обычно заключается в том, что функция должна соответствовать некоторому внешнему API - возможно, это библиотечная функция или указатель на эту функцию передается другой функции, которая ожидает этого соглашения о вызовах. Однако не все аргументы, используемые соглашением о вызовах, действительно необходимы в самой функции.

Причина упоминания имени параметра в теле - избежать предупреждений вроде

unused.c: In function l_alloc’:
unused.c:3:22: warning: unused parameter ud [-Wunused-parameter]
 void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
                      ^~

Это предупреждение можно подавить, используя фактический параметр в теле функции. Например, если у вас есть следующий оператор:

ud;

Это предупреждение теперь подавлено. Однако теперь GCC выдаст еще одно предупреждение:

unused.c:5:5: warning: statement with no effect [-Wunused-value]
     ud;
     ^~

Это предупреждение говорит о том, что оператор ud;, являясь синтаксически правильным C, вообще ни на что не влияет и, возможно, является ошибкой, в отличие от оператора

abort;

который, возможно, должен был быть написан abort();вместо этого, чтобы он что-то делал.

И вот тут-то и (void)пригодится приведение - оно однозначно и явно скажет компилятору, что оператор не должен иметь абсолютно никакого эффекта.

Антти Хаапала
источник