2011-10-17 10 views
5

Si tengo una estructura como esta:struct diseño miembros memoria

struct S { 
    ANY_TYPE a; 
    ANY_TYPE b; 
    ANY_TYPE c; 
} s; 

¿Puedo suponer que con seguridad los siguientes supuestos siempre será cierto en todas las plataformas?

((char *)&s.a) < ((char *)&s.c) 
((char *)&s.a + sizeof(s.a) + sizeof(s.b)) <= ((char *)&s.c) 

¿En C++ también?

+0

@VJo: ¿Puede explicar cómo? –

+0

¿Qué es un ejemplo de ANY_TYPE donde no se cumple? –

+0

¿Por qué querrías? El objetivo de las estructuras es acabar con este tipo de malabares. – Beta

Respuesta

3

Sí, en C como mínimo. El compilador es libre de insertar relleno después de cualquier miembro de la estructura, pero no debe reordenar los miembros.

Tampoco debe insertar relleno antes del primer miembro.

Desde C99, 6.7.2.1:

13/ Dentro de un objeto de estructura, los miembros no poco el terreno y las unidades en que los campos de bits residir tener direcciones que aumentan en el orden en que se son declarados. Un puntero a un objeto de estructura, adecuadamente convertido, apunta a su miembro inicial (o si ese miembro es un campo de bits, luego a la unidad en la que reside), y viceversa. Puede haber un relleno sin nombre dentro de un objeto de estructura, pero no al principio.

15/ Puede haber un relleno sin nombre al final de una estructura o unión.

+0

Re * Tampoco debe insertar relleno antes del primer miembro. *: Eso haría que la mayoría de los compiladores no cumplan. Agregar un vtable antes del primer miembro es un enfoque muy común para implementar el polimorfismo. –

+5

@DavidHammen En primer lugar, los vtables son un detalle de implementación de C++, no de C. En segundo lugar, el requisito de no-relleno antes del primer miembro es solo para POD (datos antiguos simples). Las clases con vtables no son POD, y por lo tanto se les permite tener a.o. un puntero vtable antes del primer miembro de datos. – Sjoerd

1

En C++ puede estar seguro de que estas suposiciones se cumplirán. En una estructura como esta, el compilador no puede cambiar el orden de los miembros.

0

Sí, de manera predeterminada los compiladores de C++ no pueden moverse alrededor de los elementos en una estructura que hace que ambas declaraciones sean triviales verdaderas.

0
  1. Sí (siempre que sizeof (ANY_TYPE) no es 0. Algunos compiladores lo permite, lo que no es estándar - ver Can sizeof return 0 (zero)). Estarías a salvo con < = o simplemente asumir un compilador estándar.

Y en C++ también.

La comparación de punteros solo tiene sentido dentro de las matrices y las estructuras/clases, generalmente no.

4

Esto es cierto para una estructura, pero cambia en C++ tan pronto como se introducen los especificadores de acceso. El compilador puede reordenar bloques enteros delimitados por especificadores de acceso.

+0

¿Es eso realmente cierto?El estándar dice que las variables miembro se inicializan en el orden en que se enumeran en la clase. Supongo que su orden relativa no se puede cambiar gracias a eso. – Xeo

+2

@Xeo Vea (por ejemplo) aquí http://stackoverflow.com/questions/4883655/access-specifier-in-c/4883764#4883764 Desafortunadamente esta respuesta no tiene cotizaciones estándar. Trataré de proporcionar algunos. En cuanto a la inicialización: la inicialización es independiente del orden de la memoria. – pmr