C число инициализации структуры элементов массива, инициализированных во время компиляции - PullRequest
1 голос
/ 30 января 2020
typedef struct
{
  struct item_t items[MAX_ITEMS];
  int num_items;
} item_list_t;`

items_list_t item_list = 
{
    .items = 
    {
#ifdef ITEM1
      {
           /* item1 initialized here */
      },
#endif
#ifdef ITEM2
      {
           /* item2 initialized here */
      },
#endif
#ifdef ITEM3
      {
           /* item3 initialized here */
      },
#endif
    }
    /* Find out how many items were initialized */
    .num_items = sizeof(items) / sizeof(struct item_t); //doesn't work
}

Я пытаюсь найти способ заполнить поле .num_items количеством элементов в массиве, которые были инициализированы во время compile . Я знаю, почему пример кода не работает, мне интересно, есть ли способ сделать это?

1 Ответ

0 голосов
/ 31 января 2020

Непереносимым хаком будет использование расширения препроцессора __COUNTER__. Это не стандартная функция C, но должна поддерживаться в последних компиляторах g cc, clang и msv c.

Препроцессор увеличивает значение счетчика после каждой оценки , так что вам нужно форсировать оценку, используя что-то вроде:

// in case __COUNTER__ was previously used in a different header
const static int initial_counter = __COUNTER__; 

#ifdef ITEM1 
  const static int item1_defined = __COUNTER__; // +1
#endif
#ifdef ITEM2
  const static int item2_defined = __COUNTER__; // +1
#endif
#ifdef ITEM3
  const static int item3_defined = __COUNTER__; // +1
#endif

// must subtract 1 because this line also evaluates __COUNTER__
const static int total_item_count = (__COUNTER__) - initial_counter - 1;

А затем:

items_list_t item_list = 
{
    .items = { ... },
    .num_items = total_item_count
}

Более портативная альтернатива препроцессора - использовать Boost , который должен быть более переносимым (но он написан для C ++, поэтому вам, возможно, придется перенести некоторые детали на C самостоятельно) или использовать генератор кода (рекомендуется).

Включение генератора кода в ваши сценарии сборки будет генерировать реальный исходный код, который вы можете добавить и отладить при необходимости. Хаки препроцессора могут легко выйти из-под контроля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...