Mam następujący funkcja czytania big-endian poczwórne (w abstrakcyjnym pliku bazowego I/O) klasy: funkcjeBłąd przesunięcia jest ujemny lub zbyt duży - poprawne rozwiązanie?
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;
}
readb() odczytuje bajt. Oto typedefs używane:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
Chodzi o to, że ja się 4 ostrzeżenia kompilatora na pierwszych czterech linii z pracy zmianowej:
ostrzeżenie C4293: „< <”: Ilość przesunięcie ujemny lub zbyt duże, niezdefiniowana zachowanie
rozumiem dlaczego występuje to ostrzeżenie, ale nie wydaje się dowiedzieć się, jak się go pozbyć poprawnie. Mogłem zrobić coś takiego:
qT |= (unsigned long long)readb() << 56
;
Powoduje usunięcie ostrzeżenia, ale czy nie ma żadnego innego problemu, czy urządzenie BYTE będzie prawidłowo przedłużane przez cały czas? Może po prostu o tym myślę za dużo, a rozwiązanie jest takie proste. Czy możecie mi pomóc? Dzięki.
Dziękuję za odpowiedź. Sam myślałem, że kompilator powinien być wystarczająco sprytny, aby zobaczyć, że przypisuję go do zmiennej wystarczająco dużej, aby pomieścić wszystkie dane (używam MSVS2008). Ale ostrzeżenie budziło wątpliwości co do poprawności mojego kodu, więc zapytałem tutaj. – PeterK
Jeśli kompilator zorientował się, co robisz z wynikiem i odpowiednio zmienia typy pośrednie, złamałoby to standard językowy. Promocja typu jest dobrze zdefiniowana, a typ wyniku operatora zależy tylko od typów argumentów. –
Od marca 2015 r. Kompilacja takiego kodu z MSVC 2013 nadal generuje ostrzeżenie. – Yadli