Communication "Packet" design by using "union" (Suggestion required)

Hello Everyone,

Story start from this thread ref:http://arduino.cc/forum/index.php/topic,159519.0.html.

To feel "union in c" I tested it in real (not only for Arduino base system) Wireless Sensor Network application. This is the format of packet

union uPacket{
  struct packet{
    char sDelimeter; //To mantian Backward Compatibilty
    uint8_t id;
    uint8_t payload[10];
    char mDelimeter; //To mantian Backward Compatibilty
    uint16_t msgId;
    char eDelimeter; //To mantian Backward Compatibilty
  }
  sPac;
  uint8_t asBytes[16];
}
uRx, uTx;

Cycle of Communication

NODE 1 NODE 2
Fill(struct) -->Send(uTx.asBytes) -... ...- Recv(&buffer) -->copy(uRx.asBytes) -->extract(struct)

Suggestion required (anything need to keep in mind?).
Thanks in advance.

Literature Links:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=115140&postdays=0&postorder=asc

http://lxr.linux.no/linux+v3.1.5/+search

http://nrqm.ca/nrf24l01/driver/

Edit: Sorry for last time posting in wrong section

One suggestion:

A union is used if data is used in different ways in the same sketch.

If you transmit and receive data, you often don't have to use an union.
A transmit function is typical: transmit( char * buffer, int size);
You can call that function with the structure: transmit( (char *) myStruct, sizeof( myStrut));

Erdin:
One suggestion:

A union is used if data is used in different ways in the same sketch.

If you transmit and receive data, you often don't have to use an union.
A transmit function is typical: transmit( char * buffer, int size);
You can call that function with the structure: transmit( (char *) myStruct, sizeof( myStrut));

Thanks. Actually this is the simplest form of (testing)message. In actual application union contain multiple stuctures for specific purpose. e.g. [header][ver][Application][][]...

Cybernetician:
Suggestion required (anything need to keep in mind?).

Don't use a union. It doesn't give you anything here.

It's mean i am doing some thing wrong?

You are posting a snippet. Why do you want the union? Show the rest of your code.

How to use this forum

Because it is the part of K&R and i am trying to feel(practice) it.

It's too long...

Thanks.

Cybernetician:
Because it is the part of K&R and i am trying to feel(practice) it.

Right.

But the real reason?

By using union lots of (heavy)function replaced by few lines of code e.g. conversion steps ,extracting different parameter, error-detecting, and performing action on them.

In short, I just wanted to make sure that use of union is not harmful for embedded systems in this case.

In short, I just wanted to make sure that use of union is not harmful for embedded systems in this case.

It depends in what way you intend to use the members.
What you are really doing by defining data as one type and aliasing it as another is type-punning.

As GCC supports its use ( mostly ) you can use it here in Arduino land, however:

  • The C99 and C11 standards allow it.
  • The C++99 and C++11 standards do not.

As you are using a char type as the second member things are different. C++ explicitly allows type-punning to a char type, whereas the other way around is undefined behaviour.

So if you write to the struct member, then read/write the array member its fine. But writing the array, then reading the struct can break strict-aliasing rules.

This makes your union usage more or less implementation defined, and therefore cannot really be considered portable: Even through future revisions. GCC currently says this:

*A member of a union object is accessed using a member of a different type.
The relevant bytes of the representation of the object are treated as an object of the type used for the access. See Type-punning. This may be a trap representation.

What this means is you can use your union fine as you have it laid out there, but consider this example:

union a{
  uint16_t b;
  uint32_t c;
  char d[ 4  ];
};

a A = { 0xFFFF };

Initialising the smaller type of a union with unequal sized members means you can only safely access d upto d[sizeof(b)-1], and c cannot be touched at all.
Whereas if c or d is the active member, reading the others is fine.

The active member is the last written to member:

[quote author=C++99: 9.5 class.union]In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time.[/quote]

This seems me what i am excepting to study BTW at this time i am considering the C99 only.

Thanks pYro_65.