简体   繁体   中英

initializing a union of structs

struct EXMPL
{
  union
  {
    struct
    {
      struct 
      {
        uint8_t AA;
        uint8_t BB;
        uint8_t CC;
        uint8_t DD;
      }Rev;

      struct
      {
        uint8_t XX;
        uint8_t VV;
        uint8_t WW;
        uint8_t FF;
      }IDs;
    };

    struct UNN
    {
      uint32_t A;
      uint32_t B; 
    };
  };
};

When I attempt to initialize this like so:

EXMPL aStruct = {{ 0x00, 0x00, 0x01, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }};

I get a "too many initializer values" error. Any help would be very much appreciated, thank you.

In C , EXMPL aStruct = {{... needs to be struct EXMPL aStruct = {{...

2 levels of {{ missing - added

int main(void) {
  struct EXMPL  // level 1
  {
    union  // level 2
    {
      struct // level 3
      {
        struct  // level 4
        {
          uint8_t AA;
          uint8_t BB;
          uint8_t CC;
          uint8_t DD;
        }Rev;

        struct
        {
          uint8_t XX;
          uint8_t VV;
          uint8_t WW;
          uint8_t FF;
        }IDs;
      } ;

      // level 3 
      // but irrelevant to initialization as only 1st union member counts by default
      struct UNN  
      {
        uint32_t A;
        uint32_t B;
      } ;
    };
  };

  struct EXMPL aStruct = {{{{ 0x00, 0x00, 0x01, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }}}};
  ...

Of course you get too many initializers error. You are using too many initializers. A union only holds exactly one of its members at any time. Not two, not three, not nine.

You should also pick a language. C and C++ are not the same by a long shot. Unions have little place in most C++ programs. They were next to useless until recently when the rules regarding what they could hold have changed, but there's still few cases when you really want or need a union.

You cannot set the outer struct to one of the union members directly. You should set one of the members of the union inside EXMPL .

As a reference please follow this simple example.

Say I have this struct definition:

    struct unionExample {
      union{    
        int integerInUnion;
        long longInUnion;
      }
    }

If you want to set the union member to an int, you have to set it like this:

struct unionExample union_example;        
union_example.integerInUnion = 5;

Just to rectify what your error is, you are trying to set the union member like this:

union_example = 5

which of course you cannot do, since union_example is of type unionExample and not int.

Going back to the example you have posted, you need to name the first struct inside your union. I will be naming it XYZ . So the code will look like this:

 struct EXMPL
{
  union
  {
    struct XYZ
    {
      struct 
      {
        uint8_t AA;
        uint8_t BB;
        uint8_t CC;
        uint8_t DD;
      }Rev;

      struct
      {
        uint8_t XX;
        uint8_t VV;
        uint8_t WW;
        uint8_t FF;
      }IDs;
    };

    struct UNN
    {
      uint32_t A;
      uint32_t B; 
    };
  };
};

You shall now set the value of XYZ like so:

EXMPL aStruct;
aStruct.XYZ = {{ 0x00, 0x00, 0x01, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }};

Can someone comment on the portability of designated initializers? In my opinion this is much clearer than however many nested brackets.

struct EXMPL aStruct = {
    .Rev = { 0xAB, 0xCD, 0xEF, 0x00 },
    .IDs = { 0x01, 0x10, 0x11, 0x00 }
};

Not to mention this allows directly initializing A and B if desired.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM