Розглянемо ці два визначення функції:
void foo() { }
void foo(void) { }
Чи є різниця між цими двома? Якщо ні, то чому самеvoid
аргумент існує? Естетичні причини?
Розглянемо ці два визначення функції:
void foo() { }
void foo(void) { }
Чи є різниця між цими двома? Якщо ні, то чому самеvoid
аргумент існує? Естетичні причини?
Відповіді:
В C :
void foo()
означає "функція, що foo
приймає не визначене число аргументів не визначеного типу" void foo(void)
означає "функція, foo
яка не бере аргументів"В C ++ :
void foo()
означає "функція, foo
яка не бере аргументів" void foo(void)
означає "функція, foo
яка не бере аргументів"Таким foo(void)
чином, пишучи , ми досягаємо однакової інтерпретації на обох мовах і робимо наші заголовки багатомовними (хоча зазвичай нам потрібно зробити ще кілька речей для заголовків, щоб зробити їх по-справжньому багатомовними; а саме, загортати їх у, extern "C"
якщо ми збираємо C ++).
void
, то це могло б уникнути проблеми "найбільш розгульного розбору".
void foo()
єдиним синтаксисом було оголошено функцію. Коли підписи були внесені, комітет C повинен був відімкнути но-параметр від старого синтаксису та ввести void foo(void)
синтаксис. C ++ сприйняв це заради сумісності.
void foo()
замість цього void foo(void)
призведе до функціональної різниці? Тобто, я користуюся версією без пустоти протягом багатьох років і не бачив жодної проблеми, я щось пропускаю?
void foo() { if ( rand() ) foo(5); }
компілює і запускає (спричиняючи невизначену поведінку, якщо вам не пощастить), тоді як void foo(void)
з тим самим органом викличе помилку компіляції.
Я усвідомлюю, що ваше питання стосується C ++, але коли мова заходить про C, відповідь можна знайти в K&R, стор. 72-73:
Крім того, якщо декларація функції не включає аргументи, як у
double atof();
це теж означає, що нічого не можна припускати щодо аргументів atof; вся перевірка параметрів вимкнена. Це особливе значення порожнього списку аргументів покликане дозволити старішим програмам С компілювати нові компілятори. Але це погана ідея використовувати його з новими програмами. Якщо функція бере аргументи, оголосити їх; якщо він не бере аргументів, використовуйте void.
C ++ 11 стандартна тяга N3337
Різниці немає.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Додаток C "Сумісність" C.1.7 Пункт 8: декларатори говорить:
8.3.5 Зміна: У C ++ функція, оголошена з порожнім списком параметрів, не містить аргументів. У C порожній список параметрів означає, що кількість та тип аргументів функції невідомі.
Приклад:
int f(); // means int f(void) in C ++ // int f( unknown ) in C
Обґрунтування: Це уникнення помилкових викликів функцій (тобто функціональних викликів з неправильним числом або типом аргументів).
Вплив на оригінальну особливість: Змінення на семантику чітко визначеної ознаки. Ця особливість була позначена як "застаріла" у C.
8.5.3 функції говорить:
4. Параметр-декларація-параметр визначає аргументи, які можна вказати, та їх обробку, коли функція викликається. [...] Якщо параметр-декларація-параметр порожній, функція не бере аргументів. Список параметрів (void) еквівалентний порожньому списку параметрів.
C99
Як згадує C ++ 11, int f()
нічого не вказує про аргументи і є застарілим.
Це може призвести до роботи коду або до UB.
Я детально інтерпретував стандарт C99 за адресою: https://stackoverflow.com/a/36292431/895245
У C ви використовуєте пустоту в порожній посиланні функції, щоб компілятор мав прототип, а цей прототип не мав аргументів. У програмі C ++ вам не потрібно говорити компілятору, що у вас є прототип, оскільки ви не можете залишити прототип.