#include <stdio.h> int main() { struct { int a; int b; } bop = {1, 2*bop.a}; printf("%d", bop.b); } Si compilado por GCC, esto imprime 2 . ¿Es esto de esperar o se basa en un comportamiento indefinido?
De C11 Standard#6.7.9p23 [énfasis añadido]
23 Las evaluaciones de las expresiones de la lista de inicialización tienen una secuencia indeterminada una con respecto a la otra y, por lo tanto, no se especifica el orden en que ocurren los efectos secundarios.152)
Entonces, bop.a puede evaluarse antes de la inicialización del miembro de estructura a . Por lo tanto, esto es UB 1) .
Una nota al pie - #6.7.9 Inicialización:
- En particular, el orden de evaluación no necesita ser el mismo que el orden de inicialización del subobjeto.
1). C11 Standard#6.3.2.1p2 [énfasis agregado]
2 Excepto cuando es el operando del operador sizeof, el operador _Alignof, el operador unario &, el operador ++, el operador -- o el operando izquierdo del . operador o un operador de asignación, un lvalue que no tiene un tipo de matriz se convierte en el valor almacenado en el objeto designado (y ya no es un lvalue); esto se llama conversión de lvalue. Si lvalue tiene un tipo calificado, el valor tiene la versión no calificada del tipo de lvalue; además, si lvalue tiene un tipo atómico, el valor tiene la versión no atómica del tipo de lvalue; de lo contrario, el valor tiene el tipo de lvalue. Si el lvalue tiene un tipo incompleto y no tiene un tipo de matriz, el comportamiento no está definido. Si el lvalue designa un objeto de duración de almacenamiento automático que podría haberse declarado con la clase de almacenamiento de registro (nunca se tomó su dirección), y ese objeto no está inicializado (no declarado con un inicializador y no se ha realizado ninguna asignación antes de su uso ), el comportamiento no está definido.