Static_cast e reinterpret_cast parecem funcionar bem para converter void * para outro tipo de ponteiro. Existe uma boa razão para favorecer um sobre o outro?
202
Static_cast e reinterpret_cast parecem funcionar bem para converter void * para outro tipo de ponteiro. Existe uma boa razão para favorecer um sobre o outro?
Respostas:
Uso
static_cast
: é o elenco mais restrito que descreve exatamente qual conversão é feita aqui.Há um equívoco de que o uso
reinterpret_cast
seria uma correspondência melhor porque significa "ignorar completamente a segurança de tipo e apenas transmitir de A para B".No entanto, isso realmente não descreve o efeito de a
reinterpret_cast
. Em vez disso,reinterpret_cast
possui vários significados, e todos afirmam que "o mapeamento realizado porreinterpret_cast
é definido pela implementação". [5.2.10.3]Mas, no caso específico de transmissão de
void*
paraT*
o mapeamento, é completamente bem definido pelo padrão; ou seja, atribuir um tipo a um ponteiro sem tipo, sem alterar seu endereço.Esta é uma razão para preferir
static_cast
.Além disso, e sem dúvida mais importante, é o fato de que todo uso de
reinterpret_cast
é absolutamente perigoso, porque converte qualquer coisa para qualquer outra coisa realmente (para ponteiros), enquantostatic_cast
é muito mais restritivo, proporcionando um melhor nível de proteção. Isso já me salvou de bugs, onde acidentalmente tentei coagir um tipo de ponteiro para outro.fonte
Esta é uma pergunta difícil. Por um lado, o Konrad faz um excelente argumento sobre a definição de especificação para reinterpret_cast , embora na prática provavelmente faça o mesmo. Por outro lado, se você estiver transmitindo entre tipos de ponteiro (como é bastante comum ao indexar na memória por um caractere *, por exemplo), static_cast gerará um erro do compilador e você será forçado a usar o reinterpret_cast de qualquer maneira.
Na prática, uso reinterpret_cast porque é mais descritivo da intenção da operação de conversão. Você certamente poderia argumentar que um operador diferente designasse apenas reinterpretações de ponteiros (que garantiam o mesmo endereço retornado), mas não há um no padrão.
fonte
reinterpret_cast
!Sugiro usar sempre o elenco mais fraco possível.
reinterpret_cast
pode ser usado para converter um ponteiro em umfloat
. Quanto mais estrutura o elenco for, mais atenção será necessária.No caso de
char*
, eu usaria elenco de estilo c, até que tenhamos algunsreinterpret_pointer_cast
, porque é mais fraco e nada mais é suficiente.fonte
float f = *reinterpret_cast<const float*>(&p);
float
, o que é falso. Os moldes de expressãovoid **
paraconst float *
, em seguida, usa uma operação dereference (que não é um elenco), para converterconst float *
afloat
.Minha preferência pessoal é baseada na alfabetização de código como esta:
ou
Os dois fazem o mesmo no final, mas static_cast parece mais apropriado em um ambiente de aplicativo de middleware, enquanto a reinterpretação do elenco parece mais algo que você veria em uma biblioteca de nível inferior IMHO.
fonte