Eu entendo a utilidade de restrict
algo como
void foo(size_t n, double * restrict a, double * restrict b)
No entanto, olhando nas páginas de manual de printf
, temos:
int fprintf(FILE *restrict stream,
const char *restrict format, ...);
Ambos os ponteiros são marcados como restrict
ed, porém apontam para tipos diferentes, portanto, no meu entendimento, eles não podem ser aliases de qualquer maneira (a menos que FILE
seja um typedef para char
), portanto restrict
não fornecem mais informações.
Estou correto ou a página de manual mostra um uso válido?
Você não está correto.
Em primeiro lugar, os valores dos ponteiros podem ser convertidos em diferentes tipos de ponteiros, portanto você não pode assumir o não-aliasing com base apenas no tipo, pelo menos não na interface de chamada de função. A função pode, em princípio, converter o
FILE *
para achar *
e usar o resultado para acessar quaisquer dados apontados. Isso nem exige a violação da regra estrita de alias, mas dependendo dos detalhes, pode violar arestrict
qualificação.Mas uma questão mais plausível nesta área seria se
FILE
fosse um tipo de estrutura (o que normalmente é), e o segundo argumento para uma chamada para esta função apontasse para um membro da estrutura apontadaFILE
. modificações nesse membro poderão violar arestrict
qualificação.Além disso, você está ignorando que
fprintf()
leva um número arbitrário de argumentos adicionais e que pode, em princípio, acessar objetos externos. Os requisitos de não-aliasing impostos porrestrict
não se tratam de pares derestrict
ponteiros qualificados. Eles tratam derestrict
ponteiros qualificados individualmente em relação a qualquer outro meio de modificação de objetos.Por último, mesmo que pudéssemos de alguma forma concluir a partir da assinatura da função (contrariamente aos factos reais) que nenhum alias relevante era possível, isso não tornaria o uso de
restrict
inválido. Seria simplesmente supérfluo.