Problem
When building a Zephyr application with CONFIG_CPP_EXCEPTIONS=y and size optimizations (CONFIG_SIZE_OPTIMIZATIONS=y), the linked libstdc++ from the Zephyr SDK has been compiled with -fno-exceptions. This means C++ exception handling does not work correctly at runtime, even though the application itself is compiled with -fexceptions.
Root Cause
The Zephyr SDK ships prebuilt multilib variants of libstdc++ that are selected at build time based on GCC's multilib resolution mechanism. Zephyr's build system queries GCC with the active compiler flags (including the optimization flag) to determine the correct library path:
# cmake/compiler/target_template.cmake
execute_process(
COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} ${COMPILER_OPTIMIZATION_FLAG} ${simple_options}
${target_flag}
--print-libgcc-file-name
...
)
However, -fexceptions / -fno-exceptions is not a multilib selection axis in the SDK's GCC build. This can be verified by running:
arm-zephyr-eabi-c++ --print-multi-lib
Since all shipped libstdc++ variants have been built with -fno-exceptions, there is no library variant with exception support available — regardless of what flags the application passes.
Current Workaround
The SDK currently works around this problem in cmake/zephyr/Kconfig by forcing speed optimizations when C++ exceptions are enabled:
# libstdc++ is built without exception support in -Os mode
choice COMPILER_OPTIMIZATIONS
default SPEED_OPTIMIZATIONS if ("$(TOOLCHAIN_VARIANT_COMPILER)" != "llvm") && CPP_EXCEPTIONS
endchoice
This selects -O2 instead of the default -Os, because the -O2 multilib variant of libstdc++ happens to be built with exception support. However, this workaround forces all applications using C++ exceptions to build with speed optimizations, removing the user's ability to choose size optimizations (-Os) — which is typically the preferred setting for embedded targets with constrained flash.
Impact
- Applications that set
CONFIG_CPP_EXCEPTIONS=y are forced into CONFIG_SPEED_OPTIMIZATIONS=y regardless of their actual size/speed requirements.
- There is no way to use both size-optimized code and working C++ exceptions simultaneously.
- If the optimization override is removed or circumvented, applications link against a libstdc++ that was built without exception support, resulting in termination if standard library throws.
Expected Behavior
When CONFIG_CPP_EXCEPTIONS=y is set, the build system should link against a libstdc++ variant that was compiled with -fexceptions, so that C++ exceptions work end-to-end — both in application code and within the standard library.
Environment
- Zephyr SDK 1.0.1
- Compiler:
arm-zephyr-eabi-c++ (GCC-based)
Problem
When building a Zephyr application with
CONFIG_CPP_EXCEPTIONS=yand size optimizations (CONFIG_SIZE_OPTIMIZATIONS=y), the linked libstdc++ from the Zephyr SDK has been compiled with-fno-exceptions. This means C++ exception handling does not work correctly at runtime, even though the application itself is compiled with-fexceptions.Root Cause
The Zephyr SDK ships prebuilt multilib variants of libstdc++ that are selected at build time based on GCC's multilib resolution mechanism. Zephyr's build system queries GCC with the active compiler flags (including the optimization flag) to determine the correct library path:
However,
-fexceptions/-fno-exceptionsis not a multilib selection axis in the SDK's GCC build. This can be verified by running:Since all shipped libstdc++ variants have been built with
-fno-exceptions, there is no library variant with exception support available — regardless of what flags the application passes.Current Workaround
The SDK currently works around this problem in
cmake/zephyr/Kconfigby forcing speed optimizations when C++ exceptions are enabled:This selects
-O2instead of the default-Os, because the-O2multilib variant of libstdc++ happens to be built with exception support. However, this workaround forces all applications using C++ exceptions to build with speed optimizations, removing the user's ability to choose size optimizations (-Os) — which is typically the preferred setting for embedded targets with constrained flash.Impact
CONFIG_CPP_EXCEPTIONS=yare forced intoCONFIG_SPEED_OPTIMIZATIONS=yregardless of their actual size/speed requirements.Expected Behavior
When
CONFIG_CPP_EXCEPTIONS=yis set, the build system should link against a libstdc++ variant that was compiled with-fexceptions, so that C++ exceptions work end-to-end — both in application code and within the standard library.Environment
arm-zephyr-eabi-c++(GCC-based)