# How to define multiple versions of a structure?

**URL:** <https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795>\
**Category:** Programming\
**Created:** [August 27, 2024, 1:01pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795 "2024-08-27T13:01:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![IraSch](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/irasch/32/1129421_2.png) [@IraSch](https://forum.arduino.cc/u/IraSch)\
**Post date:** [August 27, 2024, 1:01pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/1 "2024-08-27T13:01:22Z")

</div>

I'm wondering if this is possible with C++/Arduino and/or how the best way to address this.

My sketch needs to process information coming via RS485 data packets. The first byte of the packet identifies the packet type and thus the data structure that follows. All packets are the same length. To simplify, assume there are 3 packet structures:

```arduino
struct CmdStruct {
  byte packettype; // 1 for command packet
  byte msgno;
  byte stat;
  byte command;
  unsigned long datetime;
} PacketA ;

struct DataStruct {
  byte packettype; // 2 for data packet
  byte msgno;
  int alpha;
  int beta;
  int delta;
} PacketB ;

struct ReadStruct {
  byte msgread[8]; // This is actually used when reading from the RS485 data
} PacketR;

```

Is it possible to overlay the 3 structures so that they are referencing the same 8 bytes of memory? And if so, what's this called?

Note that in practice, the data structures are much longer.

If C++ doesn't support this, is there a way to copy PacketR to PacketA or PacketB?

Thank you.

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 27, 2024, 1:06pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/2 "2024-08-27T13:06:52Z")

</div>

> [@IraSch](#):
>
> Is it possible to overlay the 3 structures so that they are referencing the same 8 bytes of memory? And if so, what's this called?

Yes, it's called a `union`.

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [August 27, 2024, 1:15pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/3 "2024-08-27T13:15:40Z")

</div>

Yes, that is very normal. I forget how it is done in C++ but we used pointer based structures. The key is to have a standard start. The first byte must be length in order to get to the next msg, the second byte must be message type so you know what structure you are working with.  
My system did this a few million times a day for years before we were bought out and it never failed to understand and process the data.

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 27, 2024, 1:26pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/4 "2024-08-27T13:26:03Z")

</div>

> [@gfvalvo](#):
>
> Yes, it's called a `union`.

```arduino
struct __attribute__ ((packed)) CmdStruct {
  uint8_t msgno;
  uint8_t stat;
  uint8_t command;
  uint32_t datetime;
};

struct __attribute__ ((packed)) DataStruct {
  uint8_t msgno;
  int16_t alpha;
  int16_t beta;
  int16_t delta;
};

struct __attribute__ ((packed)) PacketStruct {
  uint8_t packettype;
  union {
    CmdStruct cmd;
    DataStruct data;
  };
};

void setup() {
  uint8_t rawRead[sizeof(PacketStruct)];
  // Read data from RS485 into rawRead here

  PacketStruct packetData;
  memcpy(&packetData, rawRead, sizeof(rawRead));

  if (packetData.packettype == 1) {
    // Do Command stuff with "cmd"
  } else {
    // Do Data stuff with "data"
  }
}

void loop() {
}

```

---

<div class="post-metadata">

**Author:** ![IraSch](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/irasch/32/1129421_2.png) [@IraSch](https://forum.arduino.cc/u/IraSch)\
**Post date:** [August 27, 2024, 1:30pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/5 "2024-08-27T13:30:17Z")

</div>

Thank you to all - exactly what I'm looking for.

---

<div class="post-metadata">

**Author:** ![b707](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/b707/32/854321_2.png) [@b707](https://forum.arduino.cc/u/b707)\
**Post date:** [August 27, 2024, 2:01pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/6 "2024-08-27T14:01:25Z")

</div>

> [@IraSch](#):
>
> Is it possible to overlay the 3 structures so that they are referencing the same 8 bytes of memory?

To be aware that these structures has the same size on 8bit Arduino only. If you try to send it to, say, ESP32 - these structures becames the different

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 27, 2024, 2:07pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/7 "2024-08-27T14:07:12Z")

</div>

> [@b707](#):
>
> To be aware that these structures has the same size on 8bit Arduino only. If you try to send it to, say, ESP32 - these structures becames the different

Using \<stdint.h\> types and ` __attribute__ ((packed))` fixes that.

---

<div class="post-metadata">

**Author:** ![b707](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/b707/32/854321_2.png) [@b707](https://forum.arduino.cc/u/b707)\
**Post date:** [August 27, 2024, 2:11pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/8 "2024-08-27T14:11:59Z")

</div>

I was talking about the OP's structures.

> [@gfvalvo](#):
>
> Using \<stdint.h\> types and ` __attribute__ ((packed))`

yes, it is a possible solution.

---

<div class="post-metadata">

**Author:** ![gcjr](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gcjr/32/314015_2.png) [@gcjr](https://forum.arduino.cc/u/gcjr)\
**Post date:** [August 27, 2024, 2:47pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/9 "2024-08-27T14:47:14Z")

</div>

once you know it's type, just copy it to an instance of the struct

(apparently casting a pointer to the buffer to a pointer of the struct causes grief i.e. undefined behavior)

---

<div class="post-metadata">

**Author:** ![IraSch](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/irasch/32/1129421_2.png) [@IraSch](https://forum.arduino.cc/u/IraSch)\
**Post date:** [August 27, 2024, 3:33pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/10 "2024-08-27T15:33:02Z")

</div>

I attempted to code this and I'm getting a compiler error. Here is code that deals with the structure and initialization:

```arduino
union myunion {
  byte msgread[28]; // This is actually used when reading from the RS485 data
  struct CmdStruct {
    byte client;
    byte msgno;
    byte stat;
    byte command;
    int PIN[4];
    byte Zone[16];
  } CMD;
};

void setup() {
} // end of setup
  

void loop() {
  CMD.client = 1;
  CMD.msgno = CMD.msgno+1;
  CMD.stat = 5;
  CMD.command = 255;
  CMD.PIN[0] = 1234;
  CMD.PIN[1] = 4321;
  CMD.PIN[3] = 9876;
  CMD.PIN[4] = 0;
  CMD.Zone[0] = 0;

} // end of loop

```

When compiled I get 'CMD' was not declared in this scope.

I must have some syntax wrong, but can't see it.

Using Arduino IDE 1.8.9.

---

<div class="post-metadata">

**Author:** ![RayLivingston](https://avatars.discourse-cdn.com/v4/letter/r/b5ac83/32.png) [@RayLivingston](https://forum.arduino.cc/u/RayLivingston)\
**Post date:** [August 27, 2024, 3:41pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/11 "2024-08-27T15:41:48Z")

</div>

I dont think a union is the best way to go. I think it would be a lot "cleaner" to define the basic contents of one of the structures as a base class, then define a numer of derived classes for each specific type of structure. That way you can use a pointer or reference to the base class to reference any derived class for bookkeeping, with a pointer or reference to the specific class for using/updating the unique structures.

---

<div class="post-metadata">

**Author:** ![gcjr](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gcjr/32/314015_2.png) [@gcjr](https://forum.arduino.cc/u/gcjr)\
**Post date:** [August 27, 2024, 3:51pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/12 "2024-08-27T15:51:43Z")

</div>

this kinda thing is common in communication. Ethernet frames are captured, ID'd by looking at some header bytes and the content copied to a struct that defines the sub-fields with the packet. Similar for [IP frames](https://en.wikipedia.org/wiki/IPv4) carried within an Ethernet frame and themselves carrying TCP.

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 27, 2024, 4:21pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/13 "2024-08-27T16:21:51Z")

</div>

> [@IraSch](#):
>
> I attempted to code

Even though I first suggested a `union`, I think this method will be simpler for you:

> [@gcjr](#):
>
> once you know it's type, just copy it to an instance of the struct

---

<div class="post-metadata">

**Author:** ![IraSch](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/irasch/32/1129421_2.png) [@IraSch](https://forum.arduino.cc/u/IraSch)\
**Post date:** [August 27, 2024, 4:23pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/14 "2024-08-27T16:23:06Z")

</div>

> [@RayLivingston](#):
>
> I dont think a union is the best way to go. I think it would be a lot "cleaner" to define the basic contents of one of the structures as a base class, then define a numer of derived classes for each specific type of structure.

That's fine, but for now (even as a learning point) what am I doing wrong that the union/structure code generates a compile error.

---

<div class="post-metadata">

**Author:** ![gcjr](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gcjr/32/314015_2.png) [@gcjr](https://forum.arduino.cc/u/gcjr)\
**Post date:** [August 27, 2024, 4:27pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/15 "2024-08-27T16:27:33Z")

</div>

look this over, demonstrating one approach  
(but copying is the more acceptable practice)

```arduino
struct CmdStruct {
    byte packettype; // 1 for command packet
    byte msgno;
    byte stat;
    byte command;
    unsigned long datetime;
} PacketA ;

struct DataStruct {
    byte packettype; // 2 for data packet
    byte msgno;
    int alpha;
    int beta;
    int delta;
} PacketB ;

struct ReadStruct {
    byte msgread[8]; // This is actually used when reading from the RS485 data
} PacketR;

enum { PT0, PT1, PT2 };

char s [90];

// -----------------------------------------------------------------------------
int msgno;

void
gen (
    int type,
    byte *buf,
    int nByte )
{

    switch (type) {
    case PT1:
        {
        CmdStruct *p = (CmdStruct*) buf;
        p->packettype = type;
        p->msgno = ++msgno;
        p->stat = 100;
        p->command = 99;
        p->datetime = millis ();
        }
        break;

    case PT2:
        {
        DataStruct *p = (DataStruct*) buf;
        p->packettype = type;
        p->msgno = ++msgno;
        p->alpha = 1000;
        p->beta = 2000;
        p->delta = 3000;
        }
        break;

    default:
        sprintf (s, "gen: unknown type %d", type);
        Serial.println (s);
        break;
    }
}

// -----------------------------------------------------------------------------
void
decode (
    byte *buf,
    int nByte )
{

    switch (*buf) {
    case PT1:
        {
        CmdStruct *p = (CmdStruct*) buf;
        sprintf (s, " msgno %d, stat %d command %d, datetime %lu",
            p->msgno, p->stat, p->command, p->datetime );
        Serial.println (s);
        }
        break;

    case PT2:
        {
        DataStruct *p = (DataStruct*) buf;
        sprintf (s, " msgno %d, alpha %d beta %d, delta %d",
            p->msgno, p->alpha, p->beta, p->delta );
        Serial.println (s);
        }
        break;

    }
}

// -----------------------------------------------------------------------------
void
loop (void)
{
    byte buf [90];
    if (Serial.available ()) {
        switch (Serial.read ()) {
        case 'a':
            gen (PT1, buf, sizeof(buf));
            decode (buf, sizeof(buf));
            break;

        case 'b':
            gen (PT2, buf, sizeof(buf));
            decode (buf, sizeof(buf));
            break;

        case 'z':
            gen (PT0, buf, sizeof(buf));
            break;
        }
    }
}

void
setup (void)
{
    Serial.begin (9600);
}

```

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 27, 2024, 4:38pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/16 "2024-08-27T16:38:49Z")

</div>

> [@gcjr](#):
>
> ` CmdStruct *p = (CmdStruct*) buf;`

That will invoke the undefined behavior you mentioned:

> [@gcjr](#):
>
> (apparently casting a pointer to the buffer to a pointer of the struct causes grief i.e. undefined behavior)

Your other idea was much better:

> [@gcjr](#):
>
> once you know it's type, just copy it to an instance of the struct

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 27, 2024, 4:44pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/17 "2024-08-27T16:44:58Z")

</div>

> [@IraSch](#):
>
> That's fine, but for now (even as a learning point) what am I doing wrong that the union/structure code generates a compile error.

As a learning point, you didn't define an object of type `MyUnion`:

```arduino
union MyUnion {
  byte msgread[28]; // This is actually used when reading from the RS485 data
  struct CmdStruct {
    byte client;
    byte msgno;
    byte stat;
    byte command;
    int PIN[4];
    byte Zone[16];
  } CMD;
};

MyUnion theUnion;

void setup() {
  theUnion.CMD.client = 1;
  theUnion.CMD.msgno++;
  theUnion.CMD.stat = 5;
  theUnion.CMD.command = 255;
  theUnion.CMD.PIN[0] = 1234;
  theUnion.CMD.PIN[1] = 4321;
  theUnion.CMD.PIN[2] = 9876;
  theUnion.CMD.PIN[3] = 0;
  theUnion.CMD.Zone[0] = 0;
}

void loop() {
}
```

---

<div class="post-metadata">

**Author:** ![cattledog](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cattledog/32/217816_2.png) [@cattledog](https://forum.arduino.cc/u/cattledog)\
**Post date:** [August 27, 2024, 5:08pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/18 "2024-08-27T17:08:55Z")

</div>

> [@IraSch](#):
>
> That's fine, but for now (even as a learning point) what am I doing wrong that the union/structure code generates a compile error.

I don't think that declaring the struct inside the union is correct. This compiles

```arduino
struct CmdStruct {
  byte client;
  byte msgno;
  byte stat;
  byte command;
  int PIN[4];
  byte Zone[16];
} CMD; 

union myunion {
  byte msgread[28]; // This is actually used when reading from the RS485 data
  /*struct CmdStruct {
    byte client;
    byte msgno;
    byte stat;
    byte command;
    int PIN[4];
    byte Zone[16];
  } //CMD;
  */
  struct CMD;
};

void setup() {}  

void loop() {
  CMD.client = 1;
  CMD.msgno = CMD.msgno + 1;
  CMD.stat = 5;
  CMD.command = 255;
  CMD.PIN[0] = 1234;
  CMD.PIN[1] = 4321;
  CMD.PIN[3] = 9876;
  CMD.PIN[4] = 0;
  CMD.Zone[0] = 0;
} // end of loop
```

@gfvalvo knows way more about structs and unions than I do, so his arrangement may be the way to go.

---

<div class="post-metadata">

**Author:** ![cedarlakeinstruments](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cedarlakeinstruments/32/1128931_2.png) [@cedarlakeinstruments](https://forum.arduino.cc/u/cedarlakeinstruments)\
**Post date:** [August 27, 2024, 11:45pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/19 "2024-08-27T23:45:40Z")

</div>

> [@gcjr](#):
>
> (apparently casting a pointer to the buffer to a pointer of the struct causes grief i.e. undefined behavior)

Never having tried this, I'm surprised to hear that.

However, a struct in C++ is the same thing as a class without a constructor, so an alternate way would be a base class and subclasses. I would use have a base class pointer to the data, then dereference the pointer by casting to the desired subclass.

It's a clean method and won't have any surprises. I'm not a big fan of unions.

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 27, 2024, 11:56pm UTC](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795/20 "2024-08-27T23:56:55Z")

</div>

> [@cedarlakeinstruments](#):
>
> I would use have a base class pointer to the data, then dereference the pointer by casting to the desired subclass.
> 
> It's a clean method and won't have any surprises.

It's risky at best. Casting from a base class to a subclass (downcasting) requires `dynamic_cast`. This is not supported on many small processors as it consumes code space and incurs a runtime penalty.

[Next page](https://forum.arduino.cc/t/how-to-define-multiple-versions-of-a-structure/1295795.md?page=2)
