Is there a Way to Get Warned about Misbehaving Designated Initializers?

混江龙づ霸主 提交于 2019-12-30 10:56:09

问题


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?

[Live Example]


回答1:


...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]

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) ...

...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.




回答2:


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:

const char a = f();
const float b = g();
const int c = h();

X foo = {.a = a, .b = b, .c = c};

In this case the order of function calls and the intent of the programmer is clear.



来源:https://stackoverflow.com/questions/34614308/is-there-a-way-to-get-warned-about-misbehaving-designated-initializers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!