Я думаю, что мотивация для требования, чтобы функции varargs имели именованный параметр, была для однородности va_start
.Для простоты реализации va_start
принимает имя последнего именованного параметра.При типичном соглашении о вызовах varargs и в зависимости от того, как сохранены аргументы направления, va_arg
найдет первый vararg по адресу (¶meter_name) + 1
или (first_vararg_type*)(¶meter_name) - 1
, плюс или минус некоторое заполнение для обеспечения выравнивания.
Iне думаю, что есть какая-то конкретная причина, по которой язык не может поддерживать функции varargs без именованных параметров.Должна существовать альтернативная форма va_start
для использования в таких функциях, которая должна была бы получить первый vararg непосредственно из указателя стека (или для педантизации указателя кадра, который фактически является значением, которое указывает указатель стека).имелось при входе в функцию, поскольку код в функции вполне мог бы сдвинуть sp с момента входа в функцию).В принципе это возможно - любая реализация должна каким-то образом иметь доступ к стеку [*], но это может раздражать некоторых разработчиков.Когда вы знаете соглашение о вызовах varargs, вы обычно можете реализовать макросы va_
без каких-либо других знаний, специфичных для реализации, и для этого потребуется также , зная, как напрямую получить аргументы вызова.Я реализовывал эти макросы varargs ранее, на уровне эмуляции, и это меня бы раздражало.
Кроме того, не так много практического использования для функции varargs без именованных параметров.Для функции varargs не существует языковой функции для определения типа и количества переменных аргументов, поэтому вызываемый должен все равно знать тип первого vararg, чтобы прочитать его.Так что вы могли бы также сделать его именованным параметром с типом.В printf
и его друзьях значение первого параметра сообщает функции, что типов относятся к варагам и сколько их.
IПредположим, что в теории вызываемый может взглянуть на какой-то глобальный объект, чтобы понять, как читать первый аргумент (и есть ли он вообще), но это довольно неприятно.Я, конечно, не стал бы изо всех сил поддерживать это, и добавление новой версии va_start
с дополнительным бременем реализации мешает мне.
[*] или если реализация не используетстек, к тому, что он использует вместо того, чтобы передавать аргументы функции.