Чи є різниця між foo (void) та foo () у C ++ чи C?


Відповіді:


317

В C :

  • void foo()означає "функція, що fooприймає не визначене число аргументів не визначеного типу"
  • void foo(void)означає "функція, fooяка не бере аргументів"

В C ++ :

  • void foo()означає "функція, fooяка не бере аргументів"
  • void foo(void)означає "функція, fooяка не бере аргументів"

Таким foo(void)чином, пишучи , ми досягаємо однакової інтерпретації на обох мовах і робимо наші заголовки багатомовними (хоча зазвичай нам потрібно зробити ще кілька речей для заголовків, щоб зробити їх по-справжньому багатомовними; а саме, загортати їх у, extern "C"якщо ми збираємо C ++).


10
Але якби C ++ вимагав цього void, то це могло б уникнути проблеми "найбільш розгульного розбору".
Адріан Маккарті

5
Щоправда, але в C ++ існує так багато інших хитрих синтаксичних розслідувань, що немає жодної реальності сенсуватися про жоден із них.
DrPizza

16
На нещодавнє запитання @James Kanze опублікував цікавий прийом. Поставте сюди, щоб уникнути його втрати: перші версії C не дозволили вказати кількість параметрів, яку може приймати функція, тому void foo()єдиним синтаксисом було оголошено функцію. Коли підписи були внесені, комітет C повинен був відімкнути но-параметр від старого синтаксису та ввести void foo(void)синтаксис. C ++ сприйняв це заради сумісності.
Матьє М.

3
Чи можете ви надати мені приклад C C90 і пізніше, коли використання void foo()замість цього void foo(void)призведе до функціональної різниці? Тобто, я користуюся версією без пустоти протягом багатьох років і не бачив жодної проблеми, я щось пропускаю?
чача15

6
@ chacham15 void foo() { if ( rand() ) foo(5); } компілює і запускає (спричиняючи невизначену поведінку, якщо вам не пощастить), тоді як void foo(void)з тим самим органом викличе помилку компіляції.
ММ

39

Я усвідомлюю, що ваше питання стосується C ++, але коли мова заходить про C, відповідь можна знайти в K&R, стор. 72-73:

Крім того, якщо декларація функції не включає аргументи, як у

double atof();

це теж означає, що нічого не можна припускати щодо аргументів atof; вся перевірка параметрів вимкнена. Це особливе значення порожнього списку аргументів покликане дозволити старішим програмам С компілювати нові компілятори. Але це погана ідея використовувати його з новими програмами. Якщо функція бере аргументи, оголосити їх; якщо він не бере аргументів, використовуйте void.


Але питання стосується визначень, у цьому випадку відповідним правилом C є Порожній список у деклараторі функції, який є частиною визначення цієї функції, вказує, що функція не має параметрів.
jinawee

9

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


2

У C ви використовуєте пустоту в порожній посиланні функції, щоб компілятор мав прототип, а цей прототип не мав аргументів. У програмі C ++ вам не потрібно говорити компілятору, що у вас є прототип, оскільки ви не можете залишити прототип.


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