Чому викинути невикористане значення параметра функції недійсним?


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;
}

Чи служать обидві цілі недійсними закликами?


Голосування про закриття, оскільки правильна відповідь (гальмує попередження компілятора про невикористані параметри) є в пов'язаному питанні Чарльза.
ТЕД

@Cody Grey - її закрили з цієї причини. Однак насправді це не було дублюванням цього питання. 689677 говорив про викид повернення до пустоти, а не про параметри.
ТЕД

19
Насправді обидва дублікати не відповідають цьому питанню. Один - C ++, інший - стосовно повернених значень. Це не ті самі речі . Чи є дублікати параметрів С?
Метт Столяр

2
Це питання інше, ніж те, що охоплювало запропоновані дублікати. Я бачу, чому помилка була допущена. Повторно відкрили (очевидно).
Tim Post

4
Зауважте: будь ласка, не закривайте це як дублікат питання C ++, оскільки C ++ використовує (void)дещо інший ефект. Це питання стосується C
Antti Haapala

Відповіді:


89

Саме там слід уникати попереджень компілятора, оскільки деякі параметри не використовуються.


3
Що є кращим способом для придушення попереджень: stackoverflow.com/questions/3417837 / ...
Чіро Сантіллі郝海东冠状病六四事件法轮功

@Benoit, що насправді робить кастинг для анулювання? Єдина його функція - показати компілятору, що ви навмисно щось ігноруєте або дійсно (недійсне) насправді щось робить, і коли компілятор бачить це, він просто вважатиме це тим, що зробив щось зі змінною, і тому не видає попередження?
Тан Ван

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)входить кастинг - він скаже компілятору однозначно і чітко, що твердження, як передбачається, не має абсолютно ніякого ефекту.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.