void foo()означает «функция, fooпринимающая неопределенное количество аргументов неопределенного типа»
void foo(void)означает «функция foo, не имеющая аргументов»
В C ++ :
void foo()означает «функция foo, не имеющая аргументов»
void foo(void)означает «функция foo, не имеющая аргументов»
Таким образом, при написании foo(void)мы получаем одинаковую интерпретацию для обоих языков и делаем наши заголовки многоязычными (хотя нам обычно нужно сделать что-то еще с заголовками, чтобы сделать их действительно мультиязычными, а именно, обернуть их в extern "C"компиляцию, если мы собираем C ++).
Но если бы C ++ потребовал void, то он мог бы избежать проблемы «самого неприятного анализа».
Адриан Маккарти
5
Да, но в C ++ есть много других паршивых разборов, и нет смысла в этом говорить.
DrPizza
16
На недавнем вопросе @James Kanze опубликовал интересную новость. Перепишите здесь, чтобы не потерять его: первые версии C не позволяли указывать количество параметров, которые может принимать функция, поэтому void foo()был единственным синтаксисом для объявления функции. Когда подписи были введены, комитет C должен был устранить неоднозначность со старым синтаксисом и ввести void foo(void)синтаксис. С ++ взял это ради совместимости.
Матье М.
3
Можете ли вы привести пример C C90 и более поздних версий, где использование void foo()вместо void foo(void)даст функциональную разницу? Т.е. я уже много лет пользуюсь версией без пустоты и не вижу никаких проблем, я что-то упустил?
chacham15
6
@ chacham15 void foo() { if ( rand() ) foo(5); } компилируется и запускается (вызывая неопределенное поведение, если вам не очень везет), тогда как void foo(void)с таким же телом может произойти ошибка компиляции.
ММ
39
Я понимаю, что ваш вопрос относится к C ++, но когда дело доходит до C, ответ можно найти в K & R, стр. 72-73:
Кроме того, если объявление функции не включает аргументы, как в
double atof();
это также означает, что в аргументах atof ничего не следует предполагать; проверка всех параметров отключена. Это специальное значение пустого списка аргументов предназначено для того, чтобы старые программы на С могли компилироваться с новыми компиляторами. Но это плохая идея использовать его с новыми программами. Если функция принимает аргументы, объявите их; если это не требует аргументов, используйте void.
Но вопрос касается определений, в этом случае соответствующее правило C является пустым списком в объявителе функции, который является частью определения этой функции, указывает, что у функции нет параметров.
Приложение 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.
В C вы используете 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)
синтаксис. С ++ взял это ради совместимости.void foo()
вместоvoid foo(void)
даст функциональную разницу? Т.е. я уже много лет пользуюсь версией без пустоты и не вижу никаких проблем, я что-то упустил?void foo() { if ( rand() ) foo(5); }
компилируется и запускается (вызывая неопределенное поведение, если вам не очень везет), тогда какvoid foo(void)
с таким же телом может произойти ошибка компиляции.Я понимаю, что ваш вопрос относится к C ++, но когда дело доходит до C, ответ можно найти в K & R, стр. 72-73:
источник
C ++ 11 N3337 стандартная версия
Нет никакой разницы.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Приложение C "Совместимость" C.1.7 Пункт 8: заявители говорят:
8.5.3 функции говорит:
C99
Как упоминалось в C ++ 11,
int f()
ничего не указывает на аргументы и является устаревшим.Это может привести либо к рабочему коду, либо к UB.
Я подробно интерпретировал стандарт C99 по адресу: https://stackoverflow.com/a/36292431/895245
источник
В C вы используете void в пустой ссылке на функцию, чтобы у компилятора был прототип, а у этого прототипа «нет аргументов». В C ++ вам не нужно указывать компилятору, что у вас есть прототип, потому что вы не можете пропустить этот прототип.
источник