Для эффективного обслуживания кода мне нужно убедиться, что значение в индексе 0 массива является конкретным предопределенным значением.Следующий код не работает:
#define SPECIFIC_ADDR_IDX 0
#define SPECIFIC_ADDR 8
#define NOT_SPECIFIC_ADDR1 12
#define NOT_SPECIFIC_ADDR2 16
typedef struct _struct_s
{
const uint16_t addr; // addresses are constant and are not mutable
uint32_t val;
} struct_s;
struct_s globArr[] =
{
{.addr = SPECIFIC_ADDR, .val = 0},
{.addr = NOT_SPECIFIC_ADDR1, .val = 0},
{.addr = NOT_SPECIFIC_ADDR2, .val = 0},
};
// make sure the address at the SPECIFIC_ADDR_IDX is SPECIFIC_ADDR
_Static_assert(globArr[SPECIFIC_ADDR_IDX].addr == SPECIFIC_ADDR, " Illegal!");
Это дает следующую ошибку компиляции:
error: expression in static assertion is not constant
_Static_assert (globArr[SPECIFIC_ADDR_IDX].addr == SPECIFIC_ADDR, " Illegal!");
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
addr
определяется как const uint16_t
, поэтому я подумал, что егозначение известно во время компиляции.
Есть ли эффективный способ выполнить такую проверку во время компиляции?
Уточнение: Я понимаю, что таким образом я могуИспользование _Static_assert
, const
не делает значение переменной известным во время компиляции.Я спрашиваю, знает ли кто-нибудь какой-нибудь трюк для решения таких вопросов.
Удовлетворительное решение было предложено Камилом Цуком.Инициализация может быть выполнена с указанием индекса:
struct_t globArr[] =
{
[SPECIFIC_ADDR_IDX] = { .addr = SPECIFIC_ADDR, .val = 0 },
{.addr = NOT_SPECIFIC_ADDR1, .val = 0},
{.addr = NOT_SPECIFIC_ADDR2, .val = 0},
};
В этом случае, если будет дополнительная инициализация записи в индексе [SPECIFIC_ADDR_IDX], компилятор выдаст предупреждение (не гарантируется, но большинство компиляторов будет),Просто убедитесь, что скомпилировано с warning = error option ON.