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 )
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:
read more here
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) ...
The best (read: reasonable) thing you can do in C, is to declare three temporary const variables before you initialize the struct. Their declaration order is the order of evaluation of their initializers.
Something like this:
In this case the order of function calls and the intent of the programmer is clear.