ArmandoCivini / tp2

0 stars 0 forks source link

Acá ya estás asumiendo en endianness local (esto no va a andar si lo probás en una máquina big endian) #44

Closed fedemgp closed 3 years ago

fedemgp commented 3 years ago

https://github.com/ArmandoCivini/tp2/blob/dbb347dd0054f6a6328d37578af063b4fab0df7b/file_parser.cpp#L19-L26

Supongamos que en el archivo tenés el siguiente entero

01 02

Es decir, el número 258 decimal. De ese valor estás tomando el segundo byte (0x02) y lo shifteas a izquierda 8 bits (o lo que es lo mismo, lo multiplicás por 16). Ese shifteo a izquierda te devuelve un entero en tu endianness local a lo que le sumás el primer byte.

Supongamos que tu máquina es little endian. El shifteo te termina quedando un valor 32 en decimal (o 0x0002 en little endian) + el primer byte, te termina quedando el valor 0x0102 en memoria. Por suerte, no pasó nada, y al hacer el llamado a ntohs se pasa al endianness que corresponde.

¿Pero qué pasaría si nuestra máquina fuera big endian?, el shifteo crearía un entero que en memoria se representaría de la forma 0x0200 (32 en big endian), y sumando el primer byte, te da un número que en memoria se representa de la siguiente forma 0x0201, y como estás en big endian, ntohs no va a estar ahí para salvarte las papas.

Este código no es portable, y todo por asumir un endianness local. No tendrías que haber hecho esa operación de bits, sino directamente hacer la conversión.

char buff[2] = {1, 2};
uint16_t value = ntohs(* ((uint16_t *) buff));
fedemgp commented 3 years ago

mencionado en https://github.com/ArmandoCivini/tp2/issues/18