Home > database >  _Static_assert error when expression should be true
_Static_assert error when expression should be true

Time:01-22

typedef enum
{
    eval1,
    eval2,
    eval3
} enum_t;
_Static_assert(sizeof(enum_t) == 1, "enum_t must be 1 byte");
char dummy[sizeof(enum_t) == 1];

This code compiles if the _Static_assert is commented out. The fact that dummy compiles should mean that sizeof(enum_t) == 1 evaluates to true.

Why is my _Static_assert not working?


Additional cases:

_Static_assert(sizeof(enum_t) >= 1, "");   // Passes
_Static_assert(sizeof(enum_t) == 1, "");   // Fails
_Static_assert(sizeof(enum_t) > 1, "");    // Fails
_Static_assert(!(sizeof(enum_t) > 1), ""); // Fails

I am using clang 13.0.0.

My command-line is: "C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.68/llvm/bin/clang" -cc1 -disable-free -disable-llvm-verifier -fgnuc-version=4.2.1 -mrelocation-model static -mconstructor-aliases -x c -fno-caret-diagnostics -fno-diagnostics-fixit-info -std=c17 -triple thumbv6m-none-eabi -target-cpu cortex-m0 -target-feature strict-align -target-feature soft-float -target-feature soft-float-abi -msoft-float -target-abi aapcs -mfloat-abi soft -fno-signed-char -fallow-half-arguments-and-returns -mllvm -arm-global-merge=false -nostdsysteminc -nobuiltininc "-isystemC:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.68/segger-rtl/include" "-isystemC:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 5.68/include" -D__SIZEOF_WCHAR_T=4 -D__ARM_ARCH_6M__ -D__SES_ARM -D__HEAP_SIZE__=0 -D__SES_VERSION=56800 -D__SEGGER_LINKER -DDEBUG=1 -DUSE_RTT=1 -DSTM32G031xx -D__STM32G0xx_FAMILY -D__STM32G031_SUBFAMILY -DARM_MATH_CM0PLUS -sys-header-deps -Werror -dwarf-version=4 -debug-info-kind=standalone -debug-info-macro -debugger-tuning=gdb -mllvm -generate-arange-section -exception-model=dwarf -gpubnames -fno-dwarf-directory-asm -fmath-errno -ffunction-sections -fdata-sections -fshort-enums -fno-common test.c -emit-obj -o test.o -Wall -Wextra -Wpedantic -ffunction-sections -fdata-sections

CodePudding user response:

Some compilers accept 0-length arrays. For example, testing GCC 11.2 on Godbolt.org, we can see that GCC happily compiles a 0-length array and only warns about it if the -pedantic option is used.

Therefore, you should not assume that just because char foo[x]; compiles that x is positive. If you don't want to use _Static_assert and instead want to do your assertions with using array sizes for some reason, you can do something like:

char foo[condition ? 1 : -1];

CodePudding user response:

The C standard states that each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type - and that the choice of type is implementation-defined. (ISO/IEC 9899:2018 6.7.2.2 4)

Thus, typically, in C an enum is an integer type not a char and so I would expect:

sizeof(enum_t) == sizeof(int)

Thus, for a typical 32 bit system, sizeof(int) is 4 - I suspect this is what you are seeing...

Some compilers do have a language extension that allows you to specify the size of the enumerated type... standardising this has been discussed, but it is not in C18 nor (yet!) a candidate for C2X.

  •  Tags:  
  • Related