Tengo la siguiente función para leer una palabra cuádruple-big endian (en un archivo de base abstracta de clase I/O): funcionesConteo de turno error negativo o demasiado grande - ¿solución correcta?
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;
}
El readb() lee un byte. Aquí están los typedefs utilizados:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
El caso es que me sale 4 advertencias del compilador en las primeras cuatro líneas con la operación de cambio:
advertencia C4293: '< <': valor de desplazamiento negativo o demasiado grande, no definido comportamiento
entiendo por qué se produce esta advertencia, pero me parece que no puede encontrar la manera de deshacerse de él correctamente. Podría hacer algo como:
qT |= (unsigned long long)readb() << 56
;
Esto elimina la advertencia, pero ¿no hay ningún otro problema, el BYTE se extenderá correctamente todo el tiempo? Tal vez solo estoy pensando demasiado y la solución es así de simple. ¿Pueden ayudarme aquí? Gracias.
Gracias por su respuesta. Yo mismo pensé que el compilador debería ser lo suficientemente astuto como para ver que lo estoy asignando a una variable lo suficientemente grande como para contener todos los datos (estoy usando MSVS2008). Pero la advertencia generó dudas sobre la corrección de mi código, así que pregunté aquí. – PeterK
Si el compilador se dio cuenta de lo que está haciendo con el resultado y cambia los tipos intermedios en consecuencia, estaría rompiendo el estándar de idioma. La promoción de tipo está bien definida, y el tipo de resultado de un operador solo depende de los tipos de operandos. –
A partir de marzo de 2015, la compilación de dicho código con MSVC 2013 sigue produciendo la advertencia. – Yadli