Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
operador menos unário aplicado ao tipo não assinado, resultado ainda não assinado
Observações
Os tipos não assinados contêm apenas valores não negativos. Portanto, o menos unário (negação) geralmente não faz sentido quando aplicado a um tipo não assinado. Tanto o operando quanto o resultado não são negativos.
Quando você expressa um literal inteiro negativo, o - na frente do valor é analisado como um operador de negação unário . O compilador aplica o operador depois que ele analisa o valor numérico. Se o valor numérico se encaixar no intervalo de um tipo inteiro não assinado, mas não no tipo inteiro assinado correspondente, o compilador interpretará o valor como não assinado.
Esse aviso geralmente ocorre quando você tenta expressar o valor mínimo int , -2147483648, ou o valor mínimo long long , -9223372036854775808. Esses valores não podem ser escritos como -2147483648 ou -9223372036854775808ll. A razão é porque o compilador processa a expressão em dois estágios: primeiro, ele analisa o valor numérico, depois aplica o operador de negação. Por exemplo, quando o compilador analisa -2147483648, ele segue estas etapas:
- O número 2147483648 é avaliado. Como é maior do que o valor máximo
intde 2147483647, mas ainda se encaixa em umunsigned int, o tipo de 2147483648 éunsigned int. - O menos unário é aplicado ao valor não assinado, resultando em um valor não assinado, que é 2147483648.
O tipo não assinado do resultado pode causar um comportamento inesperado. Se o resultado for usado em uma comparação, uma comparação não assinada poderá ser usada, por exemplo, quando o outro operando for um int.
Você pode evitar C4146 usando INT_MIN ou LLONG_MIN de <limits.h> ou o equivalente C++, <climits>. Esses valores têm tipos numéricos com sinal.
A opção do compilador (Ativar verificações de segurança adicionais) eleva esse aviso a um erro./sdl
Exemplo
O exemplo a seguir demonstra o comportamento inesperado que pode acontecer quando o compilador gera aviso C4146:
// C4146.cpp
// compile with: /W2
#include <iostream>
void check(int i)
{
if (i > -9223372036854775808ll) // C4146
std::cout << i << " is greater than the most negative long long int.\n";
}
int main()
{
check(-100);
check(1);
}
Neste exemplo, o compilador considera -9223372036854775808ll não assinado, mesmo que o literal tenha um ll sufixo e o operador de negação seja aplicado. Para fazer a < comparação, o compilador promove o i sinalizado para o unsigned long long int silenciosamente. A segunda linha esperada, 1 is greater than the most negative long long int, não é impressa porque ((unsigned long long int)1) > 9223372036854775808ull é falsa.
Para corrigir o exemplo, inclua <climits> e altere -9223372036854775808ll para LLONG_MIN.