Этот вопрос о функциях vararg и их последнем названном параметре перед многоточием:
void f(Type paramN, ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
Я читал в стандарте C и обнаружил следующее ограничение для макроса va_start
:
Параметр parmN является идентификатором самого правого параметра в списке переменных параметров в определении функции (тот, который находится перед, ...). Если параметр parmN объявлен с классом хранения регистров, с типом функции или массива или с типом, который не совместим с типом, который получается после применения продвижения аргументов по умолчанию, поведение не определено.
Интересно, почему поведение не определено для следующего кода
void f(int paramN[], ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
и не определено для следующего
void f(int *paramN, ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
Макросы предназначены для реализации на чистом C-коде. Но чистый код C не может выяснить, был ли paramN
объявлен как массив или как указатель. В обоих случаях тип параметра настраивается на указатель. То же самое верно для параметров типа функции.
Интересно: в чем смысл этого ограничения? Есть ли у некоторых компиляторов проблемы с реализацией этого, когда эти настройки параметров находятся внутри? (То же неопределенное поведение указано для C ++ - так что мой вопрос касается также C ++).