A MS define INVALID_HANDLE_VALUE
o seguinte (Windows SDK, handleapi.h):
#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
Por que eles fazem isso com uma conversão dupla - primeiro para LONG_PTR
(alias __int64
alias long long
em 64 bits ou long
em 32 bits) e segundo HANDLE
(alias void*
), por que não apenas:
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
Eu assumo um significado, mas não o vejo.
Acredito que isso foi feito para evitar um aviso do compilador MSVC em destinos de 64 bits (assumindo que o MSVC é o principal compilador que a MS tinha em mente para o ambiente Windows).
A conversão de um inteiro assinado de 32 bits para um tipo de ponteiro de 64 bits aciona o aviso C4312 :
Exemplo:
Gatilhos:
Demonstração ao vivo 1
Adicionar o cast
long long
antes do cast paravoid*
resolve esse aviso porque agora o cast final para um tipo de ponteiro é de um valor de 64 bits:Demonstração ao vivo 2 .
Atualização:
Como o OP comentou abaixo , ao usar um
int
literal de-1
em vez de uma variável, o compilador MSVC não emite um aviso:(veja a demonstração ).
Meu palpite é que o novo MSVC é inteligente o suficiente para ver que o cast é de fato seguro, enquanto versões mais antigas do compilador emitiam o aviso com base apenas no tipo do literal (que é
int
).Se meu palpite estiver correto, a resposta final para a pergunta é que o double cast está de fato lá por razões históricas (quando o compilador estava emitindo o aviso com base no tipo do literal).
Nota final:
O motivo também pode estar relacionado ao suporte em outros compiladores.
Curiosamente, o gcc e o clang atuais também emitem um aviso similar quando uma variável é usada ( demo ), mas não quando um literal é usado ( demo ). Então, novamente, é uma questão de razões históricas.