C99 introduced the concept of designated intializers for structs. So for example, given:
typedef struct {
int c;
char a;
float b;
} X;
I could initialize like: X foo = {.a = '\1', .b = 2.0F, .c = 4};
and calling: printf("c = %d\na = %hhu\nb = %f", foo.c, foo.a, foo.b);
would output:
c = 4
a = 1
b = 2.000000
As mentioned here this has the "surprising behavior" of assigning to c
then a
then b
, independent of the order of my designated initializers.
This becomes a real issue if I have functions like this:
int i = 0;
int f() {
return ++i;
}
int g() {
i += 2;
return i;
}
int h() {
i += 4;
return i;
}
And I want to initialize like this: X foo = {.a = (char)f(), .b = g(), .c = h()};
Now when I do: printf("c = %d\na = %hhu\nb = %f", foo.c, foo.a, foo.b);
I get:
c = 4
a = 5
b = 7.000000
The problem being there was no warning that my initialization order was not respected. Is there a warning or something I can enable for this?
...no warning that my initialization order was not respected.
A particular initialization order is an expectation based on something other then that stated in the standard. (as pointed out in the comments )
C99 section 6.7.9, p23: 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. [emphasis mine]
There is therefore no problem here except undefined (or unspecified) behavior. Very similar to other C behaviors such as the ambiguity with order of evaluation of function arguments.
EDIT
C99 has this to say about that:
from C99 §6.5.2.2p10:
Order of evaluation of function arguments is unspecified, The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
[emphasis mine]
That you would prefer a warning (which you stated well, +1) is another matter. I am not sure how practical it would be though to provide a warning for -every- -undefined- -behavior- in the C/C++ languages.
It is interesting to note some of the stated assumptions/opinions in this discussion why the C++ standards do not include Designated Initializers. (Yet) ...
...C++ is more interested in putting the flexibility on the side of the designer of a type instead, so designers can make it easy to use a type correctly and difficult to use incorrectly.