Вы не можете.Массивы в Си концептуально являются вещью времени выполнения.Нет переносимого способа навязать ему утверждение comptime.
Это не означает, что оптимизирующий компилятор не увидит его.
Если я сделаю if(!(array1[0].a == A)) abort();
и посмотрю на разборкуЯ вижу, что и gcc, и clang полностью исключают этот код, когда я компилирую с оптимизацией.
Существует трюк GCC, позволяющий вам превратить эти знания оптимизатора в утверждение времени выполнения (или утверждение ASAP какЯ называю это).
#if __GNUC__ && !__clang__
#pragma GCC diagnostic error "-Walloc-size-larger-than=999999999L"
#endif
#if NDEBUG
enum { ndebug=1};
#else
enum { ndebug=0};
#endif
#include <assert.h>
#define ASAP_ASSERT(X) \
do{ \
/*if possible, statically assert it even without the optimizer*/ \
(void)(__builtin_constant_p(X) ? sizeof(int[(X)?1:-1]) : 0); \
_Bool ASAP_ASSERT=(X); /*prevent double evaluation*/ \
if(!ndebug){ \
/*try to make the optimizer raise a -Walloc-size-larger-than=*/ \
_Bool volatile ASAP_ASSERT__[(ASAP_ASSERT)?1:-1]; \
ASAP_ASSERT__[0]=0; \
(void)ASAP_ASSERT__; \
} \
assert(ASAP_ASSERT); /*if all static assert attempts fail, do it dynamically*/ \
}while(0)
typedef enum {
A = 0,
B,
C
} enumerator1;
typedef struct {
enumerator1 a;
unsigned char foo;
unsigned char bar;
} structure1;
const structure1 array1[3] =
{
{A, 1, 1}, //This element should contain A
{C, 1, 1}, //This element should contain B
{B, 1, 1} //This element should contain C
};
#include <stdlib.h>
int main()
{
ASAP_ASSERT(array1[0].a!=A); //will cause a comptime failure on gcc when compiled with at least -O1
}
Недостатком является то, что он специфичен для GCC, имеет небольшие затраты времени выполнения (энергозависимая запись, которую можно отключить, установив ndebug в 1, но тогда вы не получитесбой времени компиляции) и у меня были некоторые ложные срабатывания.