Cross-platform C++ compatibility checker — for embedded code and PIO libraries

Cross-platform C++ compatibility checker — for embedded code and PIO libraries

C++ support varies a lot across embedded platforms. A toolchain might claim C++17, but try #include <optional> and you’ll find the macro __cpp_lib_optional is defined while the header itself doesn’t compile. For library authors the problem is worse: you’d like to use modern C++ but you don’t always know what platforms your users will target.

I built a tool that uses real PlatformIO builds (no simulation, no toolchain guessing) to test 394 SD-6 feature tests — every language feature, library type, and attribute from C++11 through C++26 — across 12 platforms: AVR, ARM Cortex-M (STM32, SAMD, nRF52, RP2040, Renesas), ESP32, ESP8266, Teensy. The results match what you’ll actually see when you build, because they are PIO builds.

What you get per (platform, standard)

Platform Standards Effective Support Usable C++
ESP32-S3 (pioarduino) C++11–C++26 C++17 / 100% C++20: 5+ 3~ · C++23: 1+ 5-
STM32 Nucleo F411RE C++11–C++20 C++14 / 97% C++17: 5+ 3~ · C++20: 1+ 7-
Raspberry Pi Pico (RP2040) C++11–C++23 C++14 / 97% C++17: 3+ 5- · C++20: 1+ 7-
AVR Arduino Uno C++11–C++17 C++11 / 86% C++17: 3+ 5-

(+ = complete · ~ = partial · - = unsupported)

Notice STM32 and RP2040 both score ~97% raw at C++14, but at C++17 STM32 has full libstdc++ (<optional>, <variant>, <filesystem>…) while RP2040 only has the language features. Raw percentages hide that; the “Usable C++” column — a curated list of high-impact tentpole features (Concepts, Ranges, <format>, Coroutines, std::optional, etc.) — makes it visible at a glance.

The tool also publishes polyfill recipes: drop-in lib_deps entries (e.g. nonstd-lite-bundle for ARM/ESP, avr-libstdcpp for AVR) that lift coverage on platforms with stripped C++ stdlibs.

Library compatibility checker

For library authors, point it at a PlatformIO library (registry name or local path) and it tells you the minimum C++ standard that works on each target platform:

# Test from the PIO registry
compat-check library ArduinoJson --report report.md

# Pin a version
compat-check library ArduinoJson@6.21.0 --report report.md

# Test a local library
compat-check library ~/my-library --report report.md

# Specific platforms only
compat-check library ~/my-library \
  --platform stm32-nucleo-f411re --platform esp32s3-arduino-v3 --platform avr-uno

Output shows the minimum working C++ standard per platform plus per-example pass/fail. There’s also a GitHub Action to run this in CI on every PR.

Links

Feedback welcome — especially platforms or libraries you’d find useful to see covered.

2 Likes

Thank you very much for this.

You might want to consider making these tests compatible with both cpptools and clangd and see if the results change.

This becomes increasingly important as PlatformIO gets tested with multiple C compilers and/or intellisense engines (e.g. cpptools vs clangd), especially when third party VSCode forks may work more easily with clangd over cpptools.

This is still somewhat fiddly with PlatformIO.

Also, there’s hybrid (both installed) - some PlatformIO forks such as pioarduino now lets you select between those two as intellisense engines, for example – e.g. use cpptools for compile but another intellisense engine based on clangd (hybrid).