c++ - uniones - typedef struct c ejemplo
C y C++: inicialización parcial de la estructura automática (5)
En C, los objetos nunca se inicializan parcialmente: si se inicializa una parte de ellos, se inicializa el objeto completo (y todos los subelementos recursivamente). Si no se proporciona un inicializador explícito, los elementos se inicializan a "cero del tipo apropiado".
La cita en su pregunta se refiere a cuando el inicializador para el objeto completo se omite por completo, no cuando un subobjeto carece de un inicializador. Por ejemplo, suponiendo que arr
tenga una duración de almacenamiento automática, entonces esto:
int arr[100] = { 123 };
inicializa arr[0]
a 123
y cada otro elemento de arr
a 0
. Mientras que esto:
int arr[100];
deja cada elemento de arr
inicializar. Es este último caso al que hace referencia la cita.
Por ejemplo, si somestruct
tiene tres miembros enteros, siempre pensé que estaba bien hacer esto en la función C (o C ++):
somestruct s = {123,};
El primer miembro se inicializaría a 123 y los dos últimos se inicializarían a 0. A menudo hago lo mismo con las matrices automáticas, escribiendo int arr[100] = {0,};
para que todos los enteros de una matriz se inicialicen a cero.
Recientemente leí en el Manual de referencia de GNU C que:
Si no inicializa una variable de estructura, el efecto depende de si tiene almacenamiento estático (consulte Especificadores de clase de almacenamiento) o no. Si es así, los miembros con tipos integrales se inicializan con 0 y los miembros del puntero se inicializan a NULL; de lo contrario, el valor de los miembros de la estructura es indeterminado.
¿Puede alguien decirme qué dicen las normas C y C ++ sobre la estructura automática parcial y la inicialización automática de la matriz? Hago el código anterior en Visual Studio sin problemas, pero quiero ser compatible con gcc / g ++, y tal vez con otros compiladores también. Gracias
La documentación de gcc vinculada no habla de Inicialización parcial , solo habla de inicialización (completa) o sin inicialización .
¿Qué es Inicialización parcial?
Los estándares no definen Inicialización parcial de objetos, ya sea Inicialización completa o Sin inicialización. La inicialización parcial es una terminología no estándar que comúnmente se refiere a una situación en la que se proporcionan algunos inicializadores, pero no todos, es decir: menos inicializadores que el tamaño de la matriz o la cantidad de elementos de la estructura que se inicializan.
Ejemplo:
int array[10] = {1,2}; //Case 1:Partial Initialization
¿Qué es Inicialización (Completa) o Sin Inicialización?
La inicialización significa proporcionar un valor inicial a la variable que se crea al mismo tiempo cuando se está creando. es decir: en la misma declaración de código.
Ejemplo:
int array[10] = {0,1,2,3,4,5,6,7,8,9}; //Case 2:Complete Initialization
int array[10]; //Case 3:No Initialization
El párrafo citado describe el comportamiento para el Case 3
.
Las reglas relativas a la Inicialización Parcial ( Case 1
) están bien definidas por el estándar y estas reglas no dependen del tipo de almacenamiento de la variable que se inicializa.
AFAIK, todos los compiladores convencionales tienen 100% de cumplimiento con estas reglas.
¿Puede alguien decirme qué dicen las normas C y C ++ sobre la estructura automática parcial y la inicialización automática de la matriz?
Los estándares C y C ++ garantizan que incluso si una matriz de enteros está ubicada en el almacenamiento automático y si hay menos inicializadores en una lista cerrada, los elementos no inicializados deben inicializarse en 0
.
C99 Norma 6.7.8.21
Si hay menos inicializadores en una lista adjunta que no hay elementos o miembros de un agregado, o menos caracteres en un literal de cadena utilizado para inicializar una matriz de tamaño conocido que no hay elementos en la matriz, el resto del agregado inicializarse implícitamente de la misma manera que los objetos que tienen una duración de almacenamiento estática.
En C ++ las reglas se establecen con una pequeña diferencia.
C ++ 03 Estándar 8.5.1 Agregados
Para 7:
Si hay menos inicializadores en la lista que miembros en el agregado, entonces cada miembro no inicializado explícitamente se inicializará en valor (8.5). [Ejemplo:
struct S { int a; char* b; int c; }; S ss = { 1, "asdf" };
inicializa
ss.a
con1
,ss.b
con"asdf"
, yss.c
con el valor de una expresión de la formaint()
, es decir,0
. ]
Mientras que la inicialización del valor se define en,
Inicializadores C ++ 03 8.5
Para 5:
Valorizar-inicializar un objeto de tipo T significa:
- si T es un tipo de clase (cláusula 9) con un constructor declarado por el usuario (12.1), entonces se llama al constructor predeterminado para T (y la inicialización está mal formada si T no tiene un constructor por defecto accesible);
- si T es un tipo de clase no sindical sin un constructor declarado por el usuario, entonces cada componente de datos no estáticos y de clase base de T tiene un valor inicializado;
- si T es un tipo de matriz, entonces cada elemento tiene un valor inicializado;
- de lo contrario, el objeto tiene cero inicialización
Las versiones más nuevas de gcc también permiten inicializar "parcialmente" y zeromem al mismo tiempo:
typedef struct{
int a,b,c;
}T;
T s = {0, .b=5};
los miembros de la estructura ahora tendrán estos valores: a=0, b=5, c=0
no tengo información sobre si otros compiladores lo permiten o no: p
Si la variable es global y estática, se asigna en el área global de binarios que se inicializa a cero. Si la variable es local, se asigna en la pila, el compilador no inicializa la memoria en la pila. (Algunas versiones de depuración pueden inicializarse, pero la versión de lanzamiento nunca lo hace)
Si la variable se asigna en Heap, el compilador tampoco la inicializa.
// You can use something like this:
typedef struct {
...;
...;
} somestruct;
// Declaration of struct
somestruct st;
// Initialising with 0. It does not depend on the size of the
// structure and the number of elements in it.
// memset() initialisation doesn''t care if struct is static or dynamic.
// but don''t forget to use st instead &st to dynamic.
memset(&st, 0, sizeof(somestruct));