¿Por qué los compiladores de C no pueden reorganizar los miembros de la estructura para eliminar el relleno de alineación? [duplicar

Posible duplicado:
¿Por qué GCC no optimiza las estructuras?
¿Por qué C ++ no hace que la estructura sea más estricta?

Considere el siguiente ejemplo en una máquina x86 de 32 bits:

Debido a las restricciones de alineación, la siguiente estructura

struct s1 {
    char a;
    int b;
    char c;
    char d;
    char e;
}

podría representarse con mayor eficiencia de memoria (12 frente a 8 bytes) si los miembros se reordenan como en

struct s2 {
    int b;
    char a;
    char c;
    char d;
    char e;
}

Sé que los compiladores de C / C ++ no pueden hacer esto. Mi pregunta es por qué el lenguaje fue diseñado de esta manera. Después de todo, podemos terminar desperdiciando grandes cantidades de memoria y referencias comostruct_ref->b @ no le importaría la diferencia.

EDITA: Gracias a todos por sus respuestas extremadamente útiles. Explica muy bien por qué la reorganización no funciona debido a la forma en que se diseñó el lenguaje. Sin embargo, me hace pensar: ¿estos argumentos seguirían siendo válidos si la reorganización fuera parte del lenguaje? Digamos que hubo alguna regla de reordenamiento especificada, de la cual requerimos al menos que

solo deberíamos reorganizar la estructura si es realmente necesario (no haga nada si la estructura ya está "apretada")the rule solo mira la definición de la estructura, no dentro de las estructuras internas. Esto garantiza que un tipo de estructura tenga el mismo diseño, sea interno o no en otra estructura el diseño de memoria compilado de una estructura dada es predecible dada su definición (es decir, la regla es fija)

Dirigiendo sus argumentos uno por uno razoné:

Mapeo de datos de bajo nivel, "elemento de menor sorpresa": Simplemente escriba sus estructuras en un estilo ajustado (como en la respuesta de @ Perry) y nada ha cambiado (requisito 1). Si, por alguna extraña razón, desea que haya relleno interno, puede insertarlo manualmente utilizando variables ficticias, y / o podría haber palabras clave / directivas.

Diferencias del compilador: El requisito 3 elimina esta preocupación. En realidad, a partir de los comentarios de @David Heffernan, parece que tenemos este problema hoy porque diferentes compiladores rellenan de manera diferente.

Mejoramient: El objetivo principal de la reordenación es la optimización (de la memoria). Veo mucho potencial aquí. Es posible que no podamos eliminar el relleno por completo, pero no veo cómo reordenar podría limitar la optimización de ninguna manera.

Type casting: Me parece que este es el mayor problema. Aún así, debería haber formas de evitar esto. Dado que las reglas están fijadas en el lenguaje, el compilador puede descubrir cómo se reordenaron los miembros y reaccionar en consecuencia. Como se mencionó anteriormente, siempre será posible evitar la reordenación en los casos en que desee un control completo. Además, el requisito 2 asegura que el código de tipo seguro nunca se romperá.

La razón por la que creo que tal regla podría tener sentido es porque me parece más natural agrupar miembros de estructura por sus contenidos que por sus tipos. También es más fácil para el compilador elegir el mejor orden que para mí cuando tengo muchas estructuras internas. El diseño óptimo incluso puede ser uno que no pueda expresar de forma segura. Por otro lado, parecería que el lenguaje es más complicado, lo que por supuesto es un inconveniente.

enga en cuenta que no estoy hablando de cambiar el idioma, solo si podría (/ debería) haber sido diseñado de manera diferente.

Sé que mi pregunta es hipotética, pero creo que la discusión proporciona una visión más profunda en los niveles inferiores de la máquina y el diseño del lenguaje.

Soy bastante nuevo aquí, así que no sé si debería generar una nueva pregunta para esto. Por favor, dime si este es el caso.

Respuestas a la pregunta(22)

Su respuesta a la pregunta