Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
um operador de subtração unária foi aplicado a tipo sem sinal, resultado permanece sem sinal
Comentários
Tipos não assinados contêm apenas valores não negativos. Portanto, a subtração unária (negação) geralmente não faz sentido quando aplicada a um tipo sem sinal. O operando e 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ária. O compilador aplica o operador depois de analisar o valor numérico. Se o valor numérico couber no intervalo de um tipo inteiro sem sinal, mas não o tipo inteiro com sinal 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 gravados como -2147483648 ou -9223372036854775808ll. Isso ocorre porque o compilador processa a expressão em duas fases: primeiro, ele analisa o valor numérico e aplica o operador de negação. Por exemplo, quando o compilador analisa -2147483648, ele segue estas etapas:
- O número 2147483648 é avaliado. Como ele é maior que o valor máximo
intde 2147483647, mas ainda cabe em umunsigned int, o tipo de 2147483648 éunsigned int. - A subtração unária é aplicada ao valor não assinado, com um resultado não assinado, que também é 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 do equivalente C++ <limits.h>, <climits>. Esses valores têm tipos assinados.
A opção do compilador /sdl (Habilitar Verificações de Segurança Adicionais) eleva esse aviso a um erro.
Exemplo
O exemplo a seguir demonstra o comportamento inesperado que pode acontecer quando o compilador gera um 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 sem sinal, embora o literal tenha um sufixo ll e o operador de negação seja aplicado. Para fazer a comparação <, o compilador promove silenciosamente o i assinado a unsigned long long int. A segunda linha esperada, 1 is greater than the most negative long long int, não é impressa porque ((unsigned long long int)1) > 9223372036854775808ull é falso.
Para corrigir o exemplo, inclua <climits> e altere -9223372036854775808ll para LLONG_MIN.