Продвижение аргументов по умолчанию в вызовах функций C
Настроить
У меня есть несколько вопросов о продвижении аргументов по умолчанию при вызове функции в C. Здесь 'секция 6.5.2.2 "Функциональные вызовы Пункты 6, 7 и 8 изСтандарт C99 (pdf) (выделение добавлено и разбито на списки для удобства чтения):
Пункт 6
Если выражение, которое обозначает вызываемую функцию, имеет тип, которыйне включает прототипцелочисленные продвижения выполняются для каждого аргумента и аргументов, которые имеют типfloat
повышены доdouble
, Это называетсяпродвижение аргумента по умолчанию.Если количество аргументов не равно количеству параметров, поведение не определено.Если функция определена с типом, которыйвключает в себя прототипи либо прототип заканчивается многоточием (, ...
) или типы аргументов после продвижения не совместимы с типами параметров, поведение не определено.Если функция определена с типом, которыйне включает прототипи типы аргументов после продвижения не совместимы с типами параметров после продвижения, поведение не определено, за исключением следующих случаев:один повышенный тип является целочисленным типом со знаком, другой повышенный тип является целочисленным типом без знака, и значение представимо в обоих типах;оба типа являются указателями на квалифицированные или неквалифицированные версии типа символа или.void
Пункт 7
Если выражение, которое обозначает вызываемую функцию, имеет тип, которыйдействительно включает в себя прототипаргументы неявно преобразуются, как если бы путем присваивания, в типы соответствующих параметров, принимая тип каждого параметра за неквалифицированную версию его объявленного типа.Многоточие в объявлении прототипа функции приводит к тому, что преобразование типа аргумента останавливается после последнего объявленного параметра.Повышение аргументов по умолчанию выполняется на конечных аргументах.Пункт 8
Никакие другие преобразования не выполняются неявно; в частности, количество и типы аргументов не сравниваются с параметрами параметров в определении функции,не включает декларатор прототипа функции.Что я знаюпродвижение аргумента по умолчанию являютсяchar
а такжеshort
к /int
unsigned int
а такжеfloat
вdouble
Необязательные аргументы для переменных функций (например,printf
) подлежат продвижению по умолчанию аргументДля записи, мое пониманиепрототип функции это:
void func(int a, char b, float c); // Function prototype
void func(int a, char b, float c) { /* ... */ } // Function definition
QuestionI»Мне действительно тяжело все это делать. Вот несколько вопросов, которые у меня есть:
Делать прототипные и непрототипированные функции поведение действительно так сильно отличается, например, в отношении продвижения по умолчанию и неявных преобразований?Когда происходит продвижение аргумента по умолчанию? Это всегда? Или это только в особых случаях (например, с помощью переменных функций)? Зависит ли это от того, является ли функция прототипом?