3

Given something like (adapted from another post):

struct {
    union {
        struct {
            float x, y, z;
        };
        float xyz[3];
    };
    int a;
} v = { /* what goes here? */ };

how do I initialize it in place? I know I have to use a designated initializer for the xyz member, but do I have to do the same if I want the first set of members instead?

...

Looking at yet another post, its examples deal only with anonymous structs, and not unions, but I guess the syntax would be

//...
} v = { someX, someY, someZ, someA };

which initializes the three members of the first variant of the union, then the int that follows the entire union part. Is this right?

Community
  • 1
  • 1
CTMacUser
  • 1,996
  • 1
  • 16
  • 27

2 Answers2

3

Anonymous structures first appeared in C11 standard.

6.7.2.1.13 stating that:

The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.

Considering examples in section 6.7.8, you have variety of choices, including very verbose ones:

struct {
    union {
        struct {
            float x, y, z;
        };
        float xyz[3];
    };
    int a;
} v = { .x = 1.0f, .y = 2.0f, .z = 3.0f, 2 };

or

struct {
    union {
        struct {
            float x, y, z;
        };
        float xyz[3];
    };
    int a;
} v = { .xyz[0] = 1.0f, .xyz[1] = 2.0f, .xyz[2] = 3.0f, .a = 2 };

Your variant with plain {1.0f, 2.0f, 3.0f, 4} gives warning warning: missing braces around initializer with Wall switched on, so does v = { {1.0, 2.0, 3.0}, 2 }. So I recommend to add explicit field description.

I tested those initializations on gcc 4.8.1 with --std=c11 -Wall -pedantic turned on.

Konstantin Vladimirov
  • 6,791
  • 1
  • 27
  • 36
  • 1- You mean c89, not c98. 2- It does not depend on the standard as much as you say: first, any initialization that worked in an older standard still works in a newer standard, and second, c11 did not add any new syntax to initialize aggregates. That leaves two methods, the newest of which was standardized 15 years ago. – Pascal Cuoq Jan 30 '14 at 08:06
  • Thanks, fixed. Of course C90 (or C89 which is earlier ANSI version) not C98. – Konstantin Vladimirov Jan 30 '14 at 08:12
  • Anonymous composites weren't supported in C until C11; I don't need to know about pre-Standard versions (i.e. extensions for C89/90/99) right now. – CTMacUser Jan 30 '14 at 17:52
  • I'm asking here because the description in the C11 standard (draft I checked) does *not* include any examples. BTW, since anonymous composites aren't considered in initialization, I'm not sure you can surround multiple terms with redundant(?) braces. (You can surround a single term with redundant braces.) – CTMacUser Jan 30 '14 at 17:56
  • Hmm... it was enlightening. I edited my answer, regarding your corrections, chose newer compiler and c11 standard option. – Konstantin Vladimirov Jan 31 '14 at 12:05
  • I think giving a warning for `{1.0f, 2.0f, 3.0f, 4}` should be a bug since elevating members within an anonymous composite is mandatory and specifying an initializer for an anonymous composite as a whole, which un-elevating members by surrounding them in braces does, is illegal. – CTMacUser Feb 04 '14 at 01:34
2
struct A{
    union B{
        struct C {
            float x, y, z;
        } S;
        float xyz[3];
    } U;
    int a;
};

int main ()
{
    struct A v = { .U.S.x = 0.0f, .U.S.y = 123.234f, .U.S.z= 123.3f };
    struct A w = { .U.xyz = {0.0f, 123.234f, 123.3f} };

    printf("\n %f %f %f  \n ",v.U.S.x, v.U.S.y ,v.U.S.z);
}
Chanakya.sun
  • 579
  • 1
  • 5
  • 13
  • An C11 anonymous composite has neither a tag nor a member name, and both the union and inner struct here have both. So your example is not applicable. – CTMacUser Jan 30 '14 at 17:45
  • ok, I have tried the same code in Linux using gcc and it works – Chanakya.sun Feb 03 '14 at 09:23
  • You missed my point. I'm asking about anonymous `struct`s and `union`s, and **nothing** *in your example is anonymous*! And I'm asking how to initialize *without* using designation. – CTMacUser Feb 04 '14 at 01:30