El compilador de compiladores estructura a bytes que son múltiplos de 2 o 4 para facilitar el acceso a ellos en código de máquina. No usaría el paquete #pragma a menos que fuera realmente necesario, y eso generalmente solo se aplica cuando se trabaja a un nivel realmente bajo (como el nivel de firmware). Wikipedia article on that.
Eso sucede porque los microprocesadores tienen operantions específicas de acceso a memoria en direcciones que son múltiplos de cuatro o dos, y eso hace que el código fuente más fácil de hacer, se utiliza la memoria más eficiente, ya veces el código es un poco Más rápido. Hay formas de detener ese comportamiento, por supuesto, como la directiva pragma pack, pero dependen de la compilación. Pero anular los valores predeterminados del compilador suele ser una mala idea, los chicos del compilador tenían una muy buena razón para hacerlo funcionar de esa manera.
Una solución mejor, para mí, sería resolver eso con C pura, que es muy, muy simple, y seguiría una buena práctica de programación, a saber: nunca confíe en lo que el compilador está haciendo con sus datos a bajo nivel.
Sé que simplemente hacer #pragma pack (1) es sexy, simple y nos da la sensación de que estamos tratando y comprendiendo directamente lo que está sucediendo en las entrañas de la computadora, y eso enciende a todos los programadores reales, pero la mejor solución es siempre la que se implementa con el idioma que está utilizando. Es más fácil de entender y, por lo tanto, más fácil de mantener; que es el comportamiento por defecto, así que debería funcionar en todas partes, y, en este caso específico, la solución C es realmente sencillo y straightfoward: acaba de leer su atributo estructura por atributos, como esto:
void readStruct(header &h, std::ifstream file)
{
file.read((char*) &h.type, sizeof(char));
file.read((char *) &h.size, sizeof(short));
}
(esto funcionará si define la estructura global, por supuesto)
Mejor aún, ya que estás trabajando con C++, sería definir un método miembro para hacer esa lectura por ti, y luego simplemente llama al myObject.readData(file)
. ¿Puedes ver la belleza y la simplicidad?
Más fácil de leer, mantener, compilar, conduce a un código más rápido y optimizado, es predeterminado.
Normalmente no me gusta meterme con las directivas de #pragma a menos que esté bastante seguro de lo que estoy haciendo. Las implicaciones pueden ser sorprendentes.
¿Cuál es 'sizeof (cabecera)'? Estoy dispuesto a apostar que es '4' ... – Cameron
Je, sí. Debería haber verificado eso. – vind