Il tipo a sinistra dell'inizializzazione non ha importanza. L'espressione -2147483648
è interpretata da sola, indipendentemente.
letterale 2147483648
non ha suffissi, il che significa che il compilatore tenterà prima di interpretarlo come un valore int
. Sulla tua piattaforma int
è apparentemente un tipo a 32 bit. Il valore 2147483648
non rientra nell'intervallo del tipo intero a 32 bit con segno. Il compilatore deve utilizzare un numero intero con segno più ampio per rappresentare il valore, se disponibile (nella sequenza int
, long int
, long long int
, con l'ultimo disponibile formalmente da C++ 11 in poi). Ma se nessun tipo intero sufficientemente ampia firmata è disponibile, il comportamento è indefinito
In MSVC storicamente long int
ha la stessa larghezza int
, anche se a 64 bit long long int
è supportata anche in versioni successive di MSVC. Tuttavia, anche in VS2013 (che supporta long long int
) ottengo
warning C4146: unary minus operator applied to unsigned type, result still unsigned
in risposta alla vostra inizializzazione. Ciò significa che MSVC si attacca ancora alle regole arcaiche C89/90 dell'interpretazione letterale dell'intero (dove i tipi sono stati scelti dalla sequenza int
, long int
, unsigned long int
).
Si noti che MSVC non è ufficialmente un compilatore C++ 11. Quindi formalmente non deve provare long long int
. Tale tipo non esiste formalmente nel linguaggio pre-C++ 11. Da questo punto di vista, MSVC non ha un numero intero con segno sufficientemente grande da utilizzare in questo caso e il comportamento non è definito. All'interno della libertà offerta da un comportamento indefinito, l'uso delle regole C89/90 per un'interpretazione letterale intera è perfettamente giustificabile.
Si potrebbe anche dare un'occhiata a questo (-2147483648> 0) returns true in C++?
Ho la sensazione che questo è cambiato in C++ 11 per dare il comportamento più sensibile si sta vedendo in precedenza con clang - Sono sicuro che un avvocato di lingua sarà presto per citare capitolo e versetto ... –
@Paul R: Il comportamento "non sensibile" esisteva solo in C89/90, dove il compilatore doveva provare 'int',' long int' e 'unsigned long int' . L'inclusione del tipo unsigned è stata una decisione sbagliata, che è stata abbandonata in C099 e nella primissima versione di C++ (C++ 98). Ora il compilatore deve provare solo i tipi firmati, in ordine di larghezza crescente. In questo caso l'unica differenza di C++ 11 è l'aggiunta di "long long int". È puramente quantitativo. – AnT
OK - grazie - forse mi stavo mescolando tra C e C++.FWIW Aggiungo sempre comunque il suffisso esplicito, quindi non devi mai pensare a quale dovrebbe essere il comportamento. –