2008-09-22 12 views
41

Los sistemas exigen que ciertas primitivas se alineen 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.¿Por qué GCC no optimiza las estructuras?

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).

Respuesta

71

gcc no reordena los elementos de una estructura, porque eso violaría el estándar C. Sección 6.7.2.1 de los estados estándar C99:

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

+5

Sí, pero ¿por qué se definió de esta manera? – nes1983

+1

@ nes1983 El programador puede hacer suposiciones en cuanto al orden de los datos en la estructura y puede estar usando el enmascaramiento para obtener cada parte. Si la estructura se reordena más que el enmascarado, sé incorrecto. – Evo510

+9

@ Evo510: Estoy confundido. Para utilizar el enmascaramiento, también debe conocer el relleno, que no está garantizado por el idioma. Entonces, no puedes usar máscaras. ¿Me estoy perdiendo de algo? – nes1983

24

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

+2

esto no tiene nada que ver con las estructuras de redes o de archivo. De hecho, el encabezado de una estructura de BMP está estrechamente empaquetado con elementos que caen en límites no naturales que son ajenos al compilador. –

+1

Err, ¿sí? Has malinterpretado la pregunta. Vuelva a leer el segundo párrafo, donde él habla sobre ordenar struct. Esto es completamente diferente del relleno. –

+6

su primer punto es muy válido. pero creo que tu segundo no es.código compilado de compiladores diferentes no es compatible de todos modos. –

1

Los compiladores de C no empaquetan automáticamente las estructuras precisamente porque son problemas de alineación como los que 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 arquitecturas RISC.

+1

No estaba hablando de deshacerme del búfer, estoy hablando de poner todos los largos/punteros de punta a punta, luego todos los cortos de punta a punta, luego todos los caracteres de punta a punta, etc. para que solo pierdas espacio al final. –

+0

Bueno, eso es verdad a medias. El compilador de C usará de forma predeterminada para empaquetarlos, simplemente lo hacen alineados a los límites de palabras naturales de la arquitectura. Es por eso que necesita #pragma paquete (0) estructuras que utilizan caracteres/cortos en los protocolos empaquetados, para evitar que agregue relleno. –

+0

@Alex, err. Vas a perder la misma cantidad de espacio, ya que tu personaje debería rellenarse la misma cantidad. No se beneficiaría en absoluto, espacio o rendimiento. –

9

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 en la reorganización de nuestras estructuras, ya que se trata de datos que, p. se puede escribir 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.

+1

Leer/Escribir estructuras directamente en un archivo no es compilador/plataforma portátil de todos modos debido a la alineación (lo cual está permitido), vea [esto] (https://stackoverflow.com/questions/5397447/struct-padding-in-c) Pues contesta. – forumulator

6

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

1

No digo 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.

+0

Creo que el kernel de Linux hace esto para las listas vinculadas. –

Cuestiones relacionadas