Рассмотрим эти два определения функций:
void foo() { }
void foo(void) { }
Есть ли разница между этими двумя? Если нет, почему void
аргумент там? Эстетические причины?
Рассмотрим эти два определения функций:
void foo() { }
void foo(void) { }
Есть ли разница между этими двумя? Если нет, почему void
аргумент там? Эстетические причины?
Ответы:
В С :
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:
Кроме того, если объявление функции не включает аргументы, как в
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 вы используете void в пустой ссылке на функцию, чтобы у компилятора был прототип, а у этого прототипа «нет аргументов». В C ++ вам не нужно указывать компилятору, что у вас есть прототип, потому что вы не можете пропустить этот прототип.