Pergunta

Estou tentando entender as diferenças entre C e C++ em relação aos ponteiros vazios.as seguintes compilações em C, mas não em C++ (todas as compilações feitas com gcc/g++ -ansi -pedantic -Wall):

int* p = malloc(sizeof(int));

Porque malloc retorna void*, que C++ não permite atribuir a int* enquanto C permite isso.

No entanto, aqui:

void foo(void* vptr)
{
}

int main()
{
    int* p = (int*) malloc(sizeof(int));
    foo(p);
    return 0;
}

Tanto C++ quanto C compilam sem reclamações.Por que?

K&R2 dizem:

Qualquer ponteiro para um objeto pode ser convertido para tipo void * sem perda de informação.Se o resultado for convertido de volta ao tipo de ponteiro original, o ponteiro original será recuperado.

E isso resume tudo o que há sobre void* conversões em C.O que o padrão C++ dita?

Foi útil?

Solução

Em C, conversões de ponteiro de e para void* estavam sempre implícitos.

Em C ++, conversões de T* para void* estão implícitos, mas void* Para qualquer outra coisa, é necessário um elenco.

Outras dicas

O C ++ é mais fortemente do que C. Muitas conversões, especialmente aquelas que implicam uma interpretação diferente do valor, requerem uma conversão explícita. o novo O operador em C ++ é uma maneira segura para alocar memória na pilha, sem um elenco explícito.

É útil entender que as conversões do tipo ponteiro não requerem realmente a execução de instruções extras da CPU.Eles são analisados ​​durante o tempo de compilação para entender as intenções do desenvolvedor. void * é um ponteiro opaco.Tudo indica que o tipo de objeto pontiagudo é desconhecido.C é digitado fracamente.Permite a conversão direta entre (void *) e qualquer (T*) implicitamente.C++ é fortemente tipado.Uma conversão de (void *) para (T*) não seria realmente um bom argumento para uma linguagem fortemente tipada.Mas o C++ tinha que permanecer compatível com versões anteriores do C, portanto, tinha que permitir tais conversões.O princípio orientador então é:explícito é melhor que implícito.Portanto, se você deseja converter um (void*) para algum específico (T*), você precisa escrevê-lo explicitamente no código.Conversão de (T*) para (void*) não requer conversão explícita, pois não há nada que se possa fazer diretamente em um ponteiro (void*) (embora seja possível chamar free()).Por isso (T*) para (void*) a conversão é praticamente segura.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top