Posso fazer aritmética no vazio * Ponteiros em C?
-
26-09-2019 - |
Pergunta
Isso é válido
void *p = &X; /* some thing */
p += 12;
E se sim, o que P agora aponta? Eu tenho o código (terceiros) que faz isso (e compila de maneira limpa) e meu palpite é que o vazio * foi tratado como um char *. Meu fiel K&R está silencioso (ish) sobre o assunto
EDIT: Meu pequeno aplicativo de teste é bom no GCC 4.1.1 e trata o vazio * como char *. Mas G ++ Barfs
Eu sei como fazer isso corretamente. Preciso saber se tenho que limpar essa base de código para encontrar todos os lugares que estão feitos.
BTW GCC -Pedantic lança um aviso
Resumo:
A especificação C é ambígua. Ele diz que em termos de representação e uso como parâmetros de função void* = char*. Mas é silencioso em relação à aritmética do ponteiro.
- O GCC (4) permite e trata como char *
- G ++ recusa
- GCC -Pedantic alerta sobre isso
- VS2010 C e C ++ recusa
Solução
Depende do compilador. Aqueles que permitem considerar o tamanho do ( *(void *)) como 1.
EDIT: É apenas para aritmético do ponteiro vazio. Não teria sentido usar neste caso as etapas do tamanho do (int) ou de 0. As expectativas comuns de alguém que o usa seria a menor etapa possível.
Outras dicas
Não, isso não é legal. UMA void*
não pode ser arbitrariamente incrementado. Ele precisa ser lançado para um tipo específico primeiro.
Se você deseja incrementá -lo por um número específico de bytes, esta é a solução que eu uso.
p = ((char*)p) + 12;
o char
O tipo é conveniente porque possui um tamanho definido de 1 byte.
EDITAR
É interessante que ele seja executado no GCC com um aviso. Eu testei no Visual Studio 2010 e verifiquei que não compilou. Meu entendimento limitado do padrão diria que o GCC no erro aqui. Você pode adicionar os seguintes sinalizadores de compilação
-Wall -ansi -pedantic
Para citar a especificação:
§6.5.6/2: Para adição, ambos os operandos devem ter tipo aritmético, ou um operando deve ser um ponteiro para um tipo de objeto e o outro terá tipo inteiro. (Incrementar é equivalente a adicionar 1.)
Um ponteiro para o vazio não é um ponteiro para um tipo de objeto, conforme esses trechos:
§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 carecem de informações necessárias para determinar seus tamanhos).
§6.2.5/19: O tipo de vazio compreende um conjunto vazio de valores; É um tipo incompleto que não pode ser concluído.
Portanto, a aritmética do ponteiro é não definido Para o ponteiro anular os tipos.
Seu palpite está correto.
Na ISO C99 padrão, Seção 6.2.5 Parágrafo 26, declara que os indicadores de vazios e os indicadores de personagem terão os mesmos requisitos de representação e alinhamento (parafraseando).
Você pode querer dar uma olhada na resposta votada superior para esta pergunta
Eu não acho que você possa, porque não sabe o tipo, portanto, não pode buscar a quantidade correta de bytes.
Lance para um tipo primeiro, ou seja, (int)
.