Conclusão final: aritmética em a void*
é ilegal em C e C ++.
O GCC permite isso como uma extensão, consulte Aritmética sobre void
- e Ponteiros de função (observe que esta seção faz parte do capítulo "Extensões C" do manual)). Clang e ICC provavelmente permitem void*
aritmética para fins de compatibilidade com o GCC. Outros compiladores (como o MSVC) desabilitam a aritmética void*
e o GCC o desabilita se o -pedantic-errors
sinalizador for especificado ou se o -Werror-pointer-arith
sinalizador for especificado (esse sinalizador é útil se sua base de código também precisar compilar com o MSVC).
O padrão C fala
As cotações são retiradas do rascunho n1256.
A descrição da norma da operação de adição indica:
6.5.6-2: Para adição, ambos os operandos devem ter um tipo aritmético ou um operando deve ser um ponteiro para um tipo de objeto e o outro deve ter um tipo inteiro.
Portanto, a questão aqui é se void*
é um ponteiro para um "tipo de objeto" ou, equivalentemente, se void
é um "tipo de objeto". A definição para "tipo de objeto" é:
6.2.5.1: Os tipos são particionados em tipos de objetos (tipos que descrevem completamente objetos), tipos de funções (tipos que descrevem funções) e tipos incompletos (tipos que descrevem objetos, mas não possuem informações necessárias para determinar seus tamanhos).
E o padrão define void
como:
6.2.5-19: O void
tipo compreende um conjunto de valores vazio; é um tipo incompleto que não pode ser concluído.
Como void
é um tipo incompleto, não é um tipo de objeto. Portanto, não é um operando válido para uma operação de adição.
Portanto, você não pode executar aritmética de ponteiro em um void
ponteiro.
Notas
Originalmente, pensava-se que a void*
aritmética era permitida, devido a essas seções do padrão C:
6.2.5-27: Um ponteiro para anular deve ter os mesmos
requisitos de representação e alinhamento que um ponteiro para um tipo de caractere.
Contudo,
Os mesmos
requisitos de representação e alinhamento devem implicar intercambiabilidade como argumentos para funções, retornar valores de funções e membros de sindicatos.
Portanto, isso significa que printf("%s", x)
tem o mesmo significado, seja x
type char*
ou void*
, mas não significa que você possa fazer aritmética em a void*
.
Nota do editor: Esta resposta foi editada para refletir a conclusão final.