0

In a software for a STM32 arm microcontroller I have a bunch of constant parameters that should be configured before compilation. These are defined as static const integers and not as #defines to enable type checking at compile time.

For example:

   static const int16_t TEMP_LIMIT_LOW = 45; //in degree celsius
   static const int16_t TEMP_LIMIT_HIGH = 60; //in degree celsius

Now I would like to ensure that the parameters are in the correct range and that the lower limit TEMP_LIMIT_LOW is always below the higher limit TEMP_LIMIT_HIGH .
To do this I tried useing static assertions. This should enable the check before the code was flashed onto the chip the first time. When I compile following code the first assert using the #define works as expected but the second one useing the static const gives the error "error: expression in static assertion is not constant"

void user_config_check(void)
{
   #define MY_VAR 45
   static_assert(MY_VAR == 45, "MY_VAR is OK"); //OK
   static const int16_t TEMP_LIMIT_LOW = 45;
   static_assert((TEMP_LIMIT_LOW == 45;), "TEMP_LIMIT_LOW is not equal to 45"); //ERROR: not constant
}

I get the same result when I use this code block outside a function.

I'm using arm-none-eabi-gcc version 10.3.1 and my compiler settings are:

-mcpu=cortex-m0plus -std=gnu11 -g3 -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage --specs=nano.specs -mfloat-abi=soft -mthumb

I read static assert in c and tried to figure out why the const type qualifier is not resutling in a constant varible but without luck.

So my questions are:

  1. Why I get this error? Is my understanding of the const type qualifier wrong?
  2. Is there a better way to do static asserts at compile time without useing #define?

I'm thankfull for every hint in the right direction.

  • 1
    In C constants variables aren't really constants, they're merely *read-only*. Therefore the compiler can't check or use their values at compile-time. – Some programmer dude Mar 21 '23 at 11:31
  • I understand that `static_assert` allows `constexpr` but only in C++, not C - so consider using `-std=gnu++20` instead of `-std=gnu11`. – Dai Mar 21 '23 at 11:34
  • 1
    Basically the C concepts of integer constants and integer constant expressions have nothing to do with `const`. C and C++ are different here. Upcoming C23 will support `constexpr` although not quite in the same way as C++. – Lundin Mar 21 '23 at 11:39
  • 1
    @Dai I believe `static constexpr int16_t TEMP_LIMIT_LOW = 45;` would also work in upcoming C23. Using gcc (trunk) build with `-std=c2x -pedantic-errors` allows it. – Lundin Mar 21 '23 at 11:41
  • [This](https://port70.net/~nsz/c/c11/n1570.html#6.7.3p11) is an illuminating example of what `const` means in C: `extern const volatile int real_time_clock;` `const` is more akin to a promise that **you** won't change the value. – Andrew Henle Mar 21 '23 at 11:57
  • Thank you for all the helpful comments. Especially the 2nd link [Why is const int x = 5; not a constant expression in C?](https://stackoverflow.com/questions/62354105/why-is-const-int-x-5-not-a-constant-expression-in-c) helped me understand, as I was too focused on the static assert during my search. – Martin Korinek Mar 21 '23 at 12:43

0 Answers0