Último parâmetro nomeado não função ou matriz?
Esta questão é sobre as funções vararg e o último parâmetro nomeado delas, antes das reticências:
void f(Type paramN, ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
Eu estava lendo no C Standard, e encontrei a seguinte restrição para ova_start
macro:
O parmN do parâmetro é o identificador do parâmetro mais à direita na lista de parâmetros da variável na definição da função (aquela imediatamente antes da, ...). Se o parâmetro parmN for declarado com a classe de armazenamento de registro, com uma função ou tipo de matriz, ou com um tipo que não é compatível com o tipo resultante após a aplicação das promoções de argumento padrão, o comportamento é indefinido.
Eu me pergunto por que o comportamento é indefinido para o seguinte código
void f(int paramN[], ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
e não indefinido para o seguinte
void f(int *paramN, ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
As macros destinam-se a ser implementadas por código C puro. Mas o código C puro não pode descobrir se é ou nãoparamN
foi declarado como uma matriz ou como um ponteiro. Em ambos os casos, o tipo do parâmetro é ajustado para ser um ponteiro. O mesmo é verdadeiro para os parâmetros do tipo de função.
Eu me pergunto: qual é a razão dessa restrição? Alguns compiladores têm problemas para implementar isso quando esses ajustes de parâmetros estão em uso internamente? (O mesmo comportamento indefinido é declarado para C ++ - então minha pergunta é sobre C ++ também).