¿Por qué GCC no optimiza las estructuras?

Los sistemas exigen que ciertas primitivas estén alineadas con ciertos puntos dentro de la memoria (entradas a bytes que son múltiplos de 4, cortos a bytes que son múltiplos de 2, etc.). Por supuesto, estos se pueden optimizar para perder el menor espacio en el relleno.

Mi pregunta es por qué GCC no hace esto automáticamente? ¿La heurística más obvia (variables de orden desde el tamaño más grande hasta el más pequeño) carece de alguna manera? ¿Algún código depende del orden físico de sus estructuras (es una buena idea)?

Solo estoy preguntando porque GCC está súper optimizado de muchas maneras, pero no en esta, y estoy pensando que debe haber una explicación relativamente buena (a la que soy ajeno).

gcc no reordena los elementos de una estructura, porque eso violaría el estándar C. La sección 6.7.2.1 de la norma C99 establece:

Dentro de un objeto de estructura, los miembros de campo no bit y las unidades en las que residen campos de bits tienen direcciones que aumentan en el orden en que se declaran.

Las estructuras se utilizan con frecuencia como representaciones de la orden de empaque de formatos de archivos binarios y protocolos de red. Esto se rompería si eso se hiciera. Además, los diferentes comstackdores optimizarían las cosas de manera diferente y sería imposible vincular el código de ambos. Esto simplemente no es factible.

GCC es más inteligente que la mayoría de nosotros en la producción de códigos de máquina de nuestro código fuente; sin embargo, tiemblo si fue más inteligente que nosotros reorganizando nuestras estructuras, ya que son datos que, por ejemplo, pueden escribirse en un archivo. Una estructura que comience con 4 caracteres y luego tenga un entero de 4 bytes sería inútil si se lee en otro sistema donde GCC decidió que debería reorganizar los miembros de la estructura.

gcc SVN tiene una optimización de reorganización de estructura (-fipa-struct-reorg), pero requiere un análisis de todo el progtwig y no es muy potente en este momento.

Los comstackdores de C no empaquetan las estructuras de manera precisa debido a problemas de alineación como usted menciona. Los accesos que no están dentro de los límites de las palabras (32 bits en la mayoría de las CPU) conllevan una gran penalización en x86 y causan trampas mortales en las architectures RISC.

No dice que sea una buena idea, pero ciertamente puede escribir código que dependa del orden de los miembros de una estructura. Por ejemplo, como un truco, a menudo las personas arrojan un puntero a una estructura como el tipo de un determinado campo dentro del que quieren acceder, luego usan la aritmética del puntero para llegar allí. Para mí, esta es una idea bastante peligrosa, pero la he visto utilizar, especialmente en C ++, para forzar el acceso público a una variable que se ha declarado privada cuando está en una clase de una biblioteca de terceros y no está públicamente encapsulada. Reordenar a los miembros lo rompería por completo.

Es posible que desee probar el último tronco de gcc o, struct-reorg-branch, que se encuentra en desarrollo activo.

https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf