0

Suppose we use avr-gcc to compile code which has the following structure:

typedef struct {
  uint8_t bLength;
  uint8_t bDescriptorType;
  int16_t wString[];
} S_string_descriptor;

We initialize it globally like this:

const S_string_descriptor sn_desc PROGMEM = {
  1 + 1 + sizeof L"1234" - 2, 0x03, L"1234"
};

Let's check what is generated from it:

000000ac <__trampolines_end>:
  ac:   0a 03           fmul    r16, r18
  ae:   31 00           .word   0x0031  ; ????
  b0:   32 00           .word   0x0032  ; ????
  b2:   33 00           .word   0x0033  ; ????
  b4:   34 00           .word   0x0034  ; ????
        ...

So, indeed string content follows the first two elements of the structure, as required.

But if we try to check sizeof sn_desc, result is 2. Definition of the variable is done in compile-time, sizeof is also a compile-time operator. So, why sizeof var does not show true size of var? And where this behavior of the compiler (i.e., adding arbitrary data to a structure) is documented?

Igor Liferenko
  • 1,499
  • 1
  • 13
  • 28
  • 1
    Related: [why static initialization of flexible array member work](https://stackoverflow.com/questions/27852062/why-static-initialization-of-flexible-array-member-work). The C standard says that a flexible array member in a struct does not increase the size of the struct (aside from possibly adding some padding at the end) but gcc lets you initialize it anyway. – Mark Plotnick Jul 23 '18 at 02:43
  • @MarkPlotnick Please make this an answer so that I could accept it. – Igor Liferenko Jul 23 '18 at 05:40

1 Answers1

1

sn_desc is a 2-byte pointer into flash. It is meant to be used with LPM et alia in order to retrieve the actual data. There is no way to get the actual size of this data; store it separately.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358