Определение структуры - PullRequest
       20

Определение структуры

2 голосов
/ 21 ноября 2019

Я столкнулся со странным кодом

static ROMCONST struct testcase * ROMCONST *patterns[] = {
  patternbmk,
  NULL
};

Этот код можно найти здесь .

Что это за определение / объявление структуры?

Может ли кто-нибудь объяснить простым языком, что это значит?

Ответы [ 3 ]

3 голосов
/ 21 ноября 2019

Относительно ROMCONST:

Что касается понимания этих объявлений, ROMCONST - это просто некоторый макрос шума, используемый вместо const.

Такие определения распространены во встроенных системах, где иногда требуется нестандартное содержимое для распределения данных во флэш-памяти. Гарвардские архитектуры, в частности, славятся этим, но также и 8/16-битными микроконтроллерами, которым могут потребоваться нестандартные указатели *far. И, наконец, в случае, если таблица размещена в EEPROM / флэш-памяти данных, она может обновляться во время выполнения, несмотря на то, что она доступна только для чтения, поэтому мы бы хотели добавить volatile. Все эти вещи могут быть спрятаны внутри ROMCONST. Таким образом, теоретически мы можем получить что-то грязное и частично нестандартное, например

#define ROMCONST volatile const far PROGMEM

(где volatile от eeprom / flash-памяти, const для любого типа флэш-памяти, far для банковской памятии PROGMEM что-то, что использовалось для объявления данных в ПЗУ на микроконтроллерах Гарварда.)

Сейчас я просто проигнорирую это и заменю на const.


Для пониманияconst -квалификаторы остальной части кода начинаются с массивов с указателями, таких как patternbmk.

const struct testcase * const patternbmk[] = {

Разбирая это:

  • struct testcase * patternbmk[]объявляет массив указателей на структуры.
  • const struct testcase * patternbmk[] предоставляет этим указателям доступ только для чтения. Указанные данные имеют значение const и не могут быть изменены с помощью этих указателей.
  • const struct testcase * const patternbmk[] делает сами указатели доступными только для чтения, что в основном служит для обеспечения того, чтобы таблица размещалась во флэш-памятивместо ОЗУ.

Может быть полезно адаптировать стиль кодирования, такой как *const, сочиняя объявление указателя и его спецификатор вместе.


Далее программистхотел объявить массив указателей на эти массивы указателей. (Как вы можете сказать, это начинает становиться грязным ...) Есть два способа, которые могут использоваться для указания на массив указателей, либо указывая на массив с помощью указателя массива , либо указывая напервый элемент массива с указателем на указатель. Программист выбрал последнее.

Элемент массива имеет тип const struct testcase * const, и, чтобы указать на такой элемент, мы добавляем дополнительный * справа, заканчивающийся const struct testcase * const *. Полезно читать такие беспорядочные объявления справа налево: указатель на const-указатель на const struct testcase.

А затем они хотели создать массив таких указателей на указатели, просто добавив [] до конца: const struct testcase * const *patterns[].

Не то чтобы каждый инициализатор в этом массиве неявно «разлагается» на указатель на первый элемент, поэтому инициализатор patternbmk затухает в &patternmk[0], который оказываетсяуказатель на const-указатель на const struct testcase, того же типа, который я обсуждал выше.

И, наконец, квалификатор static просто ограничивает область видимости переменной файлом, в котором он объявлен. NULL в конце списка инициализатора patterns является значением часового, отмечающим конец массива.

2 голосов
/ 21 ноября 2019

ROMCONST, скорее всего, директива компилятора, и это может быть что-то вроде этого: #define ROMCONST const что заставляет переменную кодировать раздел памяти.

patterns - это структура массива, которая хранит другуюструктура массива patternbmk, которая содержит указатели на функции с определением testcase struct.

static ROMCONST struct testcase * ROMCONST *patterns[] = {
  patternbmk,
  NULL
};

ROMCONST struct testcase * ROMCONST patternbmk[] = {
#if !TEST_NO_BENCHMARKS
  &testbmk1,
  &testbmk2,
  &testbmk3,
  &testbmk4,
  &testbmk5,
  &testbmk6,
  &testbmk7,
  &testbmk8,
#if CH_USE_QUEUES
  &testbmk9,
#endif
  &testbmk10,
#if CH_USE_SEMAPHORES
  &testbmk11,
#endif
#if CH_USE_MUTEXES
  &testbmk12,
#endif
  &testbmk13,
#endif
  NULL
};

ROMCONST struct testcase testbmk1 = {
  "Benchmark, messages #1",
  NULL,
  NULL,
  bmk1_execute
};

struct testcase {
  const char *name;             /**< @brief Test case name.                 */
  void (*setup)(void);          /**< @brief Test case preparation function. */
  void (*teardown)(void);       /**< @brief Test case clean up function.    */
  void (*execute)(void);        /**< @brief Test case execution function.   */
};
0 голосов
/ 21 ноября 2019

Согласно тегу , некоторые Поиск Google показывает

Документация определения макросов

#define ROMCONST   const

Модификатор константы ПЗУ.

Примечание:

В этом порту используется ключевое слово "const". Определение в строке 63 файла chtypes.h.

...