Ho la seguente funzione per la lettura di un big-endian quadword (in un file di base astratta classe I/O): funzioniErrore di conteggio negativo o troppo grande - soluzione corretta?
unsigned long long File::readBigEndQuadWord(){
unsigned long long qT = 0;
qT |= readb() << 56;
qT |= readb() << 48;
qT |= readb() << 40;
qT |= readb() << 32;
qT |= readb() << 24;
qT |= readb() << 16;
qT |= readb() << 8;
qT |= readb() << 0;
return qT;
}
Il readb() Legge un byte. Ecco le typedef usati:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
Il fatto è che ottengo 4 avvisi del compilatore sulle prime quattro righe con l'operazione di spostamento:
avvertimento C4293: '< <': valore di scorrimento negativo o troppo grandi, non definito comportamento
capisco perché si verifica questo avvertimento, ma io non riesco a capire come sbarazzarsi di esso correttamente. Potrei fare qualcosa del tipo:
qT |= (unsigned long long)readb() << 56
;
Questo rimuove l'avviso, ma non ci sono altri problemi, il BYTE sarà correttamente esteso per tutto il tempo? Forse ci sto pensando troppo e la soluzione è così semplice. Ragazzi, potete aiutarmi qui? Grazie.
Grazie per la risposta. Io stesso pensavo che il compilatore dovesse essere abbastanza intelligente da vedere che lo sto assegnando a una variabile abbastanza grande da contenere tutti i dati (sto usando MSVS2008). Ma l'avvertimento ha messo in dubbio la correttezza del mio codice, quindi ho chiesto qui. – PeterK
Se il compilatore ha capito cosa si sta facendo con il risultato e si modifica di conseguenza i tipi intermedi, si rompe lo standard della lingua. La promozione del tipo è ben definita e il tipo di risultato di un operatore dipende sempre solo dai tipi di operandi. –
A partire da marzo 2015, la compilazione di tale codice con MSVC 2013 produce ancora l'avviso. – Yadli