Почему функции без определенных аргументов можно вызывать с любым количеством аргументов?

В C, если функция определена с 0 аргументами (пустой список параметров), вызывается с любым количеством аргументов, gcc не выдает никакой ошибки. Почему это так?

3 ответа

TL; DR - int func(void) {.. а также int func() {.. не то же самое.

  • В первом случае путем явного упоминания void в качестве типа параметра (идентификатор не требуется) обратите внимание, что функция определена как таковая, поэтому входного параметра нет, поэтому при вызове он не должен передавать никаких аргументов.

  • В последнем случае не выполняется проверка количества передаваемых аргументов, поэтому вам разрешено передавать любое количество и тип аргументов.


Замечания:

Согласно C11 Глава §6.9.1

Если декларатор включает список типов параметров, объявление каждого параметра должно включать идентификатор, за исключением особого случая списка параметров, состоящего из одного параметра типа void , в этом случае не должно быть идентификатора. Список объявлений не должен следовать.

Потому что так C-спецификации определяют функцию.

Если вы хотите, чтобы функция не принимала аргументов, явно укажите void в списке аргументов.

Если вы хотите, чтобы функция принимала переменное число аргументов, используйте переменные аргументы ..., Или в древнем C вы можете оставить список аргументов пустым, и компилятор будет применять продвижение по умолчанию для каждого аргумента.

Хотя последнее сейчас устарело: из раздела 6.11.6 Деклараторы функций C11 spec n1570 draft

Использование деклараторов функций с пустыми скобками (не деклараторы типа параметров в формате prototype) является устаревшей функцией.

Рассмотрим этот кусок кода:

//void Test(int a);

int main()
{
  int a = 0;
  Test();
  return 0;
}

Он будет компилироваться (в основном с предупреждением в зависимости от компилятора, настроек и т. Д.), Потому что компилятор предполагает, что Test это функция, принимающая любое количество аргументов и возвращающая int, Это также называется "неявное объявление". Вы никогда не должны использовать эту устаревшую функцию языка C.

Если вы раскомментируете первую строку void Test(int a);, он больше не будет компилироваться, потому что теперь компилятор знает, что Test это функция, возвращающая int и взять ровно один int аргумент и как мы называем Test() без аргументов компилятор может выдать ошибку, потому что аргументы при вызове не совпадают с аргументами функции, когда она была объявлена.

Теперь мы можем задать вопрос: почему неявное объявление разрешено в первую очередь? Ну, это так, как язык был разработан. ИМО это ошибка дизайна.

Другие вопросы по тегам