Рассмотрим эти два определения функций:
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"
, если мы' повторная компиляция С++).
void
, то можно было бы избежать самой неприятной проблемы синтаксического анализа.
- person Adrian McCarthy; 04.01.2010
void foo()
был единственным синтаксисом для объявления функции. Когда были введены подписи, комитет C должен был устранить неоднозначность отсутствия параметра из старого синтаксиса и ввел синтаксис void foo(void)
. С++ взял его ради совместимости.
- person Matthieu M.; 14.09.2011
void foo()
вместо void foo(void)
приведет к функциональной разнице? т.е. Пользуюсь версией без пустоты уже много лет и проблем не заметил, я что-то упустил?
- person chacham15; 07.11.2011
std::vector<int> v(std::vector<int>());
или любой комбинации двух типов, построение одного непосредственно в конструкторе другого.
- person Yam Marcovic; 27.05.2015
void foo() { if ( rand() ) foo(5); }
компилируется и запускается (вызывая неопределенное поведение, если вам не очень повезло), тогда как void foo(void)
с тем же телом вызовет ошибку компиляции.
- person M.M; 23.12.2015
extern "C"
вокруг имен C.
- person DrPizza; 10.08.2018
if (getchar() == 'x') 1/0;
, поведение не определено только в том случае, если выполнение достигает этой строки и дается определенный ввод.
- person M.M; 21.01.2021
rand()
; если происходит возврат 0
, то неопределенного поведения нет: наличие foo(5)
в коде, который никогда не выполняется, не означает, что программа имеет UB. Я не путаю УБ с симптомами УБ. Возможно, пример getchar()
лучше, чем пример rand()
, чтобы продемонстрировать этот момент, чтобы избежать споров о гарантиях последовательности чисел, сгенерированных rand()
- person M.M; 21.01.2021
Я понимаю, что ваш вопрос относится к C++, но когда дело доходит до C, ответ можно найти в K&R, страницы 72-73:
Кроме того, если объявление функции не включает аргументы, как в
double atof();
это также означает, что ничего не следует делать в отношении аргументов atof; проверка всех параметров отключена. Это специальное значение пустого списка аргументов предназначено для того, чтобы старые программы на C могли компилироваться новыми компиляторами. Но использовать его с новыми программами — плохая идея. Если функция принимает аргументы, объявите их; если он не принимает аргументов, используйте 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
Как упоминалось в С++ 11, int f()
ничего не указывает на аргументы и устарело.
Это может привести либо к рабочему коду, либо к UB.
Я подробно интерпретировал стандарт C99 по адресу: https://stackoverflow.com/a/36292431/895245.
В C вы используете пустоту в пустой ссылке на функцию, так что у компилятора есть прототип, и этот прототип не имеет «аргументов». В C++ вам не нужно сообщать компилятору, что у вас есть прототип, потому что вы не можете пропустить прототип.