Order of execution for struct initializer

Viewed 118
#include <stdio.h>

int main()
{
    struct {
        int a;
        int b;
    } bop = {1, 2*bop.a};

    printf("%d", bop.b);
}

If compiled by GCC, this prints 2. Is this to be expected or is it relying on undefined behavior?

1 Answers

From C11 Standard#6.7.9p23 [emphasis added]

23 The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified.152)

So, bop.a can be evaluated before initialisation of structure member a. Hence, this is UB1).

A footnote - #6.7.9 Initialization:

  1. In particular, the evaluation order need not be the same as the order of subobject initialization.

1). C11 Standard#6.3.2.1p2 [emphasis added]

2 Except when it is the operand of the sizeof operator, the _Alignof operator, the unary & operator, the ++ operator, the -- operator, or the left operand of the . operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion. If the lvalue has qualified type, the value has the unqualified version of the type of the lvalue; additionally, if the lvalue has atomic type, the value has the non-atomic version of the type of the lvalue; otherwise, the value has the type of the lvalue. If the lvalue has an incomplete type and does not have array type, the behavior is undefined. If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

Related