0

In many cases I find that I would like to have access to raw data in union but I dont want to calculate the size or I want to keep it flexible.

For example (a bit artificial, but I hope it conveys the idea), I dont want to adjust the size of raw if I change how othertype_t looks like:

#pragma pack(push, 1)
typedef union {
  uint8_t raw[0];
  struct {
    uint8_t bar[32];
    othertype_t foo[4];
  };
} sometype_t;
#pragma pack(pop)

Later I can do things like sizeof(union sometype_t) to know the size of raw.

Using raw[0] works but I know that is a gcc non-standard extension. How can I do this in a more portable way?

As a 'trick', I could do something like raw[1] but it feels a bit misleading.

Update: Someone indicated that this is undefined behavior in C++. Could you include some additional information about this?

Juan Leni
  • 6,982
  • 5
  • 55
  • 87
  • why the negative vote? – Juan Leni Aug 11 '18 at 12:51
  • 1
    Are you asking about C or C++? Because in C++, there is no portable way of type-punning with unions like that, it's undefined behavior… – Michael Kenzel Aug 11 '18 at 12:52
  • 1
    If you give the structure a name you could do raw[sizeof structname] or similar. – Fantastic Mr Fox Aug 11 '18 at 12:53
  • 1
    @purpletentacle Some people think that type punning is a bad idea, and some people like to downvote questions about what they think are bad ideas. – Steve Summit Aug 11 '18 at 12:55
  • 1
    @MichaelKenzel Thanks! Let's keep the discussion around C. I think it makes more sense in this context. (I updated the tags) – Juan Leni Aug 11 '18 at 12:57
  • @SteveSummit Even if people disagree with type punning, the question is still valid. Downvoting or closing does not makes sense. – Juan Leni Aug 11 '18 at 12:59
  • 1
    @purpletentacle I didn't say it made sense. I usually don't agree with such downvoting. I didn't downvote here. You asked why someone downvoted, and I gave you my (admittedly speculative) answer. – Steve Summit Aug 11 '18 at 13:00
  • @SteveSummit Thanks Steve! Yes, I understood you were trying to help. – Juan Leni Aug 11 '18 at 13:01
  • Well, you could define an array type, [0..65535] of uint8_t, say. You could then either unionize that in on top, (if only handling pointers so that you never have to actually allocate that much memory:), or set a pointer of that type to the same address as the struct. – Martin James Aug 11 '18 at 13:05
  • I usually do this: `struct foo {...}; byte raw[BIG_ENOUGH]; do_stuff( (struct foo*)raw);` Of course, consider required alignment. – ddbug Aug 12 '18 at 01:30
  • @ddbug yes, I should have added the `pragma pack` in the question – Juan Leni Aug 12 '18 at 08:52
  • @purpletentacle Why did you add C++ tag? – HolyBlackCat Dec 24 '18 at 08:44
  • Somebody indicated that this is undefined behavior in C++. I think it is important that this is explained too. It can lead to a lot of problems. – Juan Leni Dec 24 '18 at 08:48
  • I undid the edit, and nowhere I said it's undefined behavior. I said anonymous structures are not valid C++. They aren't part of the language, period. – StoryTeller - Unslander Monica Dec 24 '18 at 08:48
  • @StoryTeller This is what I meant: `Because in C++, there is no portable way of type-punning with unions like that, it's undefined behavior… – Michael Kenzel ` – Juan Leni Dec 24 '18 at 08:50
  • There's no need to re-iterate that information here, [it's already on SO](https://stackoverflow.com/questions/25664848/unions-and-type-punning). – StoryTeller - Unslander Monica Dec 24 '18 at 08:51
  • Excellent! Thanks! – Juan Leni Dec 24 '18 at 08:51

1 Answers1

1

Maybe

typedef union 
{
  struct _struct
  {
    uint8_t bar[32];
    othertype_t foo[4];
  };
  uint8_t raw[sizeof(struct _struct)];
} sometype_t;
0___________
  • 60,014
  • 4
  • 34
  • 74