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)is1, 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 error
enum, effectively treating thestatic_assertas:
_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)
- Code analysis reports:
What I’ve tried
- Confirmed via generated compile commands / CMake that
-fshort-enumsis 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_tsyntax 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
- Is there a way to make CLion’s C language engine respect
-fshort-enumsfor 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?
-
- If not, is there a recommended workaround for this kind of configuration? For example:
- Project / toolchain level setting telling CLion “assume
-fshort-enumsfor 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.
- Project / toolchain level setting telling CLion “assume
Thanks!
请先登录再写评论。