CLion inspection disagrees with GCC -fshort-enums (Zephyr toolchain)

Environment

  • IDE: CLion (2025.2.4)
  • Toolchain: Zephyr SDK (GCC-based, embedded ARM)
  • Compiler flags: The toolchain adds -fshort-enums
  • Language level: C11 (no C23 enum-width features available in the toolchain)

Problem

I’m working on an embedded project built with the Zephyr SDK. Zephyr’s build system passes -fshort-enums to GCC, and some enums are laid out using the smallest integer type that can represent all their values (1 byte in my case)

I rely on this behavior and enforce it with compile‑time assertions, for example:

typedef enum
{
    msg_type_invalid = 0x00,
    msg_type_ping    = 0x01,
    msg_type_pong    = 0x02,
    msg_type_max
} msg_type_t;

BUILD_ASSERT(sizeof(msg_type_t) == sizeof(uint8_t),
             "msg_type_t should be 1 byte");

  • The actual compiler (GCC with -fshort-enums) accepts this.
    sizeof(msg_type_t) is 1, the static assert passes, and the code runs correctly on the target.
  • CLion’s code analysis / inspection, however, assumes that is 4 bytes and flags this as a compile-time errorenum, effectively treating the static_assert as:

_Static_assert(sizeof(msg_type_t) == 1, "msg_type_t should be 1 byte");
// CLion thinks this is: 4 == 1 -> false

So in the editor I see an error like:

static_assert failed: 'msg_type_t should be 1 byte' Expression (4 == 1) evaluates to false

…but the real build succeeds.

Why I can’t just use C23 enum-width syntax

If I change the enum to:

typedef enum : uint8_t
{
    msg_type_invalid = 0x00,
    msg_type_ping    = 0x01,
    msg_type_pong    = 0x02,
    msg_type_max
} msg_type_t;

then CLion’s inspection is happy (it now understands the enum is 1 byte).
However, the Zephyr toolchain’s GCC (and/or language standard settings) does not support C23-style enum : uint8_t syntax, so this fails to compile for real.

So I’m stuck between:

  • -fshort-enums + static_assert:
    • real compiler: OK
    • CLion inspection: ERROR (thinks sizeof(enum) is 4)
  • enum : uint8_t:
    • real compiler: ERROR (unsupported syntax)
    • CLion inspection: OK

I need the first behavior (portable C11 + toolchain flags), but I’d like CLion to understand that this particular toolchain uses -fshort-enums and hence sizeof(enum) can be 1.

Minimal example

#include <stdint.h>

typedef enum
{
    packet_type_invalid = 0x00,
    packet_type_data    = 0x01,
    packet_type_ack     = 0x02,
    packet_type_max
} packet_type_t;

_Static_assert(sizeof(packet_type_t) == sizeof(uint8_t),
               "packet_type_t should be 1 byte");

  • With GCC + -fshort-enums: builds fine.
  • In CLion, with the project configured to use the real toolchain:
    • Code analysis reports:
      static_assert failed: 'packet_type_t should be 1 byte' (4 == 1)

What I’ve tried

  • Confirmed via generated compile commands / CMake that -fshort-enums is indeed passed to GCC and used for the actual build.
  • Manually compiling the minimal example outside CLion: sizeof(packet_type_t) is 1 as expected.
  • Using enum : uint8_t syntax to appease CLion (works in the IDE, fails in the real toolchain).
  • Playing with language standard settings in CLion (C11 vs later) – no change; the inspection still treats the enum as 4 bytes.

So, What I am asking

  1. Is there a way to make CLion’s C language engine respect -fshort-enums for a given toolchain/project, so that:
    • sizeof(enum) matches the actual compiler behavior, and
    • my _Static_assert(sizeof(enum_type) == sizeof(uint8_t)) is evaluated correctly in the IDE?
  2. If not, is there a recommended workaround for this kind of configuration? For example:
    • Project / toolchain level setting telling CLion “assume -fshort-enums for this project”.
    • Some way to override the presumed enum size for inspections.
    • A way to mark these assertions or macros so that CLion doesn’t try to evaluate them, but still keeps other static asserts active.

Thanks!

0

Please sign in to leave a comment.