Обзор и история
Из-за истории развития языка C int a()
не означает, что «a
не принимает аргументов и возвращает int
». Это означает, что «a
принимает неуказанные аргументы и возвращает int
».
Поскольку «неуказанные аргументы» номинально совместимы с «одним аргументом, который является int
», компилятор не выдает ошибку для конфликтующих типов. Из-за дополнительных правил в C (см. «Совместимость функций» ниже) типы несовместимы, но компилятор не обязан это диагностировать.
Первоначально в C функции были объявлены со списком параметров ()
, и вызывающая сторона должна была предоставить правильные типы. (Кроме того, аргументы были «повышены»; аргументы char
были преобразованы в int
и т. д., но это отдельная проблема.) Если функция была определена, она была определена с именами параметров, такими как int a(b)
, и объявлениями. следующих параметров, например:
int a()
int b;
{
return 6*b;
}
Но это было только для определения. В объявлении не было этих объявлений типов параметров.
Позже, чтобы улучшить информацию о типах функций, C добавил грамматику для полных объявлений функций, включая типы параметров, такие как int a(int b)
. Однако, поскольку старая грамматика уже использовала int a()
для обозначения «неуказанных параметров», язык должен был сохранить это значение для поддержки старого кода.
Вместо этого была назначена специальная форма, означающая «без параметров», то есть помещать void
в список параметров отдельно. int a(void)
означает, что «a
— это функция, не принимающая параметров и возвращающая int
». Итак, если вы объявите функцию как int a(void);
, а затем определите ее как int a(int b) { … }
, компилятор выдаст вам сообщение об ошибке.
Совместимость функций
Одно из правил совместимости типов функций в C 2018 6.7.6.3 15 гласит:
… Если один тип имеет список типов параметров, а другой тип указан в определении функции, которое содержит (возможно, пустой) список идентификаторов, оба должны согласоваться по количеству параметров,…
Объявление int a(int b);
имеет список типов параметров с одним параметром.
Это определение:
int a(){
return 6;
}
имеет пустой список идентификаторов и между int a()
и {
не определяет никаких параметров. Вот и не сошлись в количестве параметров. Однако от компилятора не требуется диагностировать эту несовместимость.
person
Eric Postpischil
schedule
14.06.2020