Почему `sizeof var` не показывает истинный размер?

Предположим, мы используем avr-gcc для компиляции кода, который имеет следующую структуру:

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

Мы инициализируем его глобально следующим образом:

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

Давайте проверим, что из него генерируется:

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  ; ????
        ...

Таким образом, строковое содержимое следует за первыми двумя элементами структуры, как и требуется.

Но если мы попытаемся проверить sizeof sn_desc, результат будет 2. Определение переменной выполняется во время компиляции, sizeof также является оператором времени компиляции. Итак, почему sizeof var не показывает истинный размер var? И где задокументировано такое поведение компилятора (т.е. добавление произвольных данных в структуру)?


person Igor Liferenko    schedule 23.07.2018    source источник
comment
Связано: почему работает статическая инициализация гибкого элемента массива. Стандарт C говорит, что гибкий элемент массива в структуре не увеличивает размер структуры (кроме возможного добавления некоторого заполнения в конце), но gcc все равно позволяет вам его инициализировать.   -  person Mark Plotnick    schedule 23.07.2018
comment
@MarkPlotnick Пожалуйста, сделайте это ответом, чтобы я мог его принять.   -  person Igor Liferenko    schedule 23.07.2018


Ответы (1)


sn_desc — это 2-байтовый указатель на флэш-память. Он предназначен для использования с LPM и другими для получения фактических данных. Невозможно получить фактический размер этих данных; хранить отдельно.

person Ignacio Vazquez-Abrams    schedule 23.07.2018