2

I am doing some network programming, and I use some struct to describe my frame header like that:

struct my_frame_header {
    uint16_t field1;
    uint16_t field2;
};

And so, when I have a buffer frame I can do something like that:

uint8_t buffer[BUFFER_SIZE];
struct my_frame_header *frame_header = (struct my_frame_header *)buffer;

my_read(buffer, BUFFER_SIZE);

I can now access to the header field like that:

ntohl(frame_header->field1);

Now, my question is: What is the most elegant way to access the data after the structure? (i.e. to get a pointer at the beginning of the data part)

jmlemetayer
  • 4,774
  • 1
  • 32
  • 46
  • 1
    This breaks strict aliasing rules, doesn't it? – dhein Jan 28 '15 at 09:45
  • Thanks, I didn't known [this rule](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule). But it seems that, by using an `uint8_t buffer[]` it is ok. – jmlemetayer Jan 28 '15 at 09:54
  • I would say thats right, but not at all. I suppose if you are on a machine with CHAR_BIT > 8 you will get trouble. But I can't confirm, as I never worked on such machine. – dhein Jan 28 '15 at 10:20
  • @Zaibis Not really, I am running this on a microcontroller, so it should be ok. Thanks for the information – jmlemetayer Jan 28 '15 at 10:30
  • My concern is, the Standard states that only `char`, `unsigned char` and `signed char` or equilent sized types pointer are allowed to alias in that way. So If you are on a i.e. 16 bit machine, you would break that rule by aliasing it with `uint8_t` – dhein Jan 28 '15 at 10:50

2 Answers2

1

Well, if I understood your question correctly, you can do something like

uint8_t * data = (uint8_t *)buffer + sizeof (struct my_frame)

then, data will be a pointer to the next uint8_t element after the header.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1
uint8_t buffer[BUFFER_SIZE];
struct my_frame_header *frame_header = (struct my_frame_header *)buffer;

This is wrong, the base address of buffer can be unaligned for my_frame_header.

Take look to Memory access and alignment

On the other hand:

The block that malloc gives you is guaranteed to be aligned so that it can hold any type of data.

Then, you can use malloc in order to skip this problem:

uint8_t *buffer = malloc(BUFFER_SIZE);
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • Not an answer, but very useful. Thanks. As suggested in the article, I will add some compiler directive to correct this. – jmlemetayer Jan 28 '15 at 10:10
  • Unfortunately, I am running this on a microcontroller with endless loop tasks (freertos) and data on the stack. So I will really need to check this out. – jmlemetayer Jan 28 '15 at 10:28