Skip to content

chore: standardize on C++23 across examples, host tests, docs and CI - #844

Merged
finger563 merged 1 commit into
esp-cpp:mainfrom
owenpkent:chore/cpp23-everywhere
Oct 12, 2026
Merged

finger563 merged 1 commit into
esp-cpp:mainfrom
owenpkent:chore/cpp23-everywhere

Conversation

@owenpkent

@owenpkent owenpkent commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Description

Follow-up to #843 and the Slack discussion: espp should be C++23 minimum everywhere. The library targets (lib/CMakeLists.txt, lib/espp.cmake, pc/CMakeLists.txt) already require C++23, but most of the repo around them still said C++20. This PR moves all of it to 23:

  • 143 example CMakeLists.txt: set(CMAKE_CXX_STANDARD 20) → 23 (the ~8 examples that already said 23 are unchanged). The telemetry example's comment, which explained why it stayed on 20, is updated to match.
  • Host-test build lines in the test headers of basicmicro, canopen (both), desktop, dispatcher, hid-rp (3 of 4; the reports test already said 23), mcp266 (both), monitor, odrive_native (both), ota, stream_frame, system, usb_device/xinput and wdi (all 4), plus pc/tests/odrive_native_golden.cpp: -std=c++20 → -std=c++23.
  • READMEs and the doc/en RST pages that mirror them: the copy-paste build commands, and the prose ("depends only on the C++20 standard library", "requires a C++20 compiler", etc.) now say C++23. References to C++20 language features (concepts, requires clauses, designated initializers) are left alone since they are describing the feature, not the standard level.
  • Things that actually build with the flag: .github/workflows/desktop_tests.yml, components/odrive_native/interop/run_interop.sh, components/odrive_native/python/tests/test_odrive.py.
  • components/rtps/example/pc/CMakeLists.txt: cxx_std_17 → cxx_std_23.
  • .github/copilot-instructions.md code-style note: C++20 → C++23.

components/rtps/REFACTOR_PLAN.md still records the original "DECIDED: C++20" decision point; its header already says the repo moved to C++23, so I left the historical record alone.

Motivation and Context

The hid-rp host tests are the concrete case: hid-rp-switch-pro.hpp uses C++23 decay-copy (auto(x)), so the -std=c++20 build line in three of the four hid-rp test headers could never have worked with clang. More generally, the standard was already 23 for the library but 20 for everything that documents or exercises it, which is confusing for anyone building the host tests or copying an example as a starting point.

Note on the example CMakeLists.txt change: it is a consistency change only, the value has no effect on what the firmware compiles with. Measured from build/compile_commands.json on both IDF 5.5.1 and 6.0.2:

  • 134 of the 143 examples set CMAKE_CXX_STANDARD after project(). In IDF that is after every component target has been created, so no -std= flag is derived from it at all. The compile line carries only IDF's own flag: -std=gnu++2b on 5.5.1, -std=gnu++26 on 6.0.2.
  • The 9 that set it before project() get -std=gnu++23 -std=gnu++2b (5.5.1) or -std=gnu++23 -std=gnu++26 (6.0.2). Last flag wins, so IDF's still applies.

Either way the espp sources were already being built at C++23 or newer on device; the 20 in the examples was just misleading.

How has this been tested?

Windows 11, clang 22.1.8 with the MSVC STL, every standalone host test built with clang++ -std=c++23 -Wall -Wextra:

  • 22 pass: basicmicro, canopen, canopen simulated_node, desktop, dispatcher, hid_rp_3dconnexion, hid_rp_gamepad, hid_rp_report_map, mcp266 (both), monitor, odrive_native (host + stream), odrive_native golden, ota, stream_frame, system, xinput, wdi (device, hid, host, protocol).
  • hid_rp_reports_host_test fails the DualSense num_data_bytes == 9 static_assert under the MSVC ABI. This is the pre-existing issue from the fix(hid-rp): bump hid-rp submodule to pick up missing <bit> include #843 discussion and is unrelated to the standard (it fails the same way at -std=c++20, plus the auto(x) errors).
  • odrive_native_interop_device.cpp needs <sys/select.h>, so it was not built here; it is POSIX-only by design.

pre-commit run (clang-format) passes on the changed files.

ESP-IDF: hid-rp/example builds cleanly for esp32s3 on both IDF v5.5.1 (the CI version) and v6.0.2; thread_pool/example configured on both to check the before-project() case. Flags above are from those builds.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update
  • Software change

Checklist:

  • My change requires a change to the documentation.
  • I have added / updated the documentation related to this change via either README or WIKI

Software

  • I have added tests to cover my changes.
  • I have updated the .github/workflows/build.yml file to add my new test to the automated cloud build github action.
  • All new and existing tests passed.
  • My code follows the code style of this project.

The library targets (lib/, pc/) already require C++23, but most of the repo
around them still said C++20: 143 example CMakeLists set CMAKE_CXX_STANDARD 20,
the host-test build lines and the READMEs / RST pages that mirror them used
-std=c++20, the desktop_tests CI job and the odrive_native interop scripts
built with c++20, and the rtps pc example pinned cxx_std_17.

Move all of it to C++23 and update the prose ("depends only on the C++20
standard library", "requires a C++20 compiler") and the copilot code-style
note to match. References to C++20 language features (concepts, requires
clauses, designated initializers) are unchanged.

The hid-rp host tests are the concrete motivation: hid-rp-switch-pro.hpp uses
C++23 decay-copy (auto(x)), so the -std=c++20 build line in three of the four
test headers could never have worked with clang.
Copilot AI balanced review requested due to automatic review settings October 11, 2026 20:40
@github-actions

Copy link
Copy Markdown

✅Static analysis result - no issues found! ✅

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Most example standard assignments occur too late to affect ESP-IDF targets, and several canonical headers still document C++20.

5 open findings
What changed in this PR

Standardizes examples, host tests, documentation, and CI on the repository’s C++23 minimum.

Changes:

  • Updates ESP-IDF and host-side build settings to C++23.
  • Revises test commands and documentation accordingly.
  • Updates CI and Copilot guidance to reference C++23.
File Description
.github/​copilot-instructions.md Updates coding guidance to C++23.
.github/​workflows/​desktop_tests.yml Builds desktop host tests with C++23.
lib/​README_PYPI.md Documents the C++23 build requirement.
pc/​tests/​odrive_native_golden.cpp Updates the documented host command.
doc/​en/​data/​reflect_cpp.rst Documents the C++23 requirement.
doc/​en/​dispatcher/​custom_modules.rst Updates the host-test command.
doc/​en/​motor_control/​basicmicro.rst Updates the documented library level.
doc/​en/​motor_control/​mcp266.rst Updates the documented library level.
doc/​en/​stream_frame/​stream_frame.rst Updates the documented library level.
components/​adc/​example/​CMakeLists.txt Selects C++23 for the example.
components/​adrc/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ads1x15/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ads7138/​example/​CMakeLists.txt Selects C++23 for the example.
components/​adxl345/​example/​CMakeLists.txt Selects C++23 for the example.
components/​as5600/​example/​CMakeLists.txt Selects C++23 for the example.
components/​at581x/​example/​CMakeLists.txt Selects C++23 for the example.
components/​aw9523/​example/​CMakeLists.txt Selects C++23 for the example.
components/​basicmicro/​example/​CMakeLists.txt Selects C++23 for the example.
components/​basicmicro/​README.md Updates the host-test command.
components/​basicmicro/​test/​basicmicro_host_test.cpp Updates the documented test command.
components/​bdc_driver/​example/​CMakeLists.txt Selects C++23 for the example.
components/​binary-log/​example/​CMakeLists.txt Selects C++23 for the example.
components/​bldc_current_sense/​example/​CMakeLists.txt Selects C++23 for the example.
components/​bldc_motor/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ble_gatt_server/​example/​CMakeLists.txt Selects C++23 for the example.
components/​bm8563/​example/​CMakeLists.txt Selects C++23 for the example.
components/​bmi270/​example/​CMakeLists.txt Selects C++23 for the example.
components/​bq27220/​example/​CMakeLists.txt Selects C++23 for the example.
components/​button/​example/​CMakeLists.txt Selects C++23 for the example.
components/​byte90/​example/​CMakeLists.txt Selects C++23 for the example.
components/​canopen/​example/​CMakeLists.txt Selects C++23 for the example.
components/​canopen/​README.md Updates the documented library level.
components/​canopen/​test/​canopen_host_test.cpp Updates the documented test command.
components/​canopen/​can_bridge_example/​CMakeLists.txt Selects C++23 for the bridge example.
components/​canopen/​can_bridge_example/​README.md Updates the simulated-node command.
components/​canopen/​can_bridge_example/​test/​simulated_node_host_test.cpp Updates the documented test command.
components/​chsc6x/​example/​CMakeLists.txt Selects C++23 for the example.
components/​cli/​example/​CMakeLists.txt Selects C++23 for the example.
components/​cobs/​example/​CMakeLists.txt Selects C++23 for the example.
components/​color/​example/​CMakeLists.txt Selects C++23 for the example.
components/​controller/​example/​CMakeLists.txt Selects C++23 for the example.
components/​cst816/​example/​CMakeLists.txt Selects C++23 for the example.
components/​csv/​example/​CMakeLists.txt Selects C++23 for the example.
components/​desktop/​example/​CMakeLists.txt Selects C++23 before project setup.
components/​desktop/​test/​desktop_host_test.cpp Updates the documented test command.
components/​dispatcher/​example/​CMakeLists.txt Selects C++23 for the example.
components/​dispatcher/​README.md Updates the host-test command.
components/​dispatcher/​test/​dispatcher_host_test.cpp Updates the documented test command.
components/​display_drivers/​example/​CMakeLists.txt Selects C++23 for the example.
components/​dns_server/​example/​CMakeLists.txt Selects C++23 for the example.
components/​drv2605/​example/​CMakeLists.txt Selects C++23 for the example.
components/​encoder/​example/​CMakeLists.txt Selects C++23 for the example.
components/​esp-box/​example/​CMakeLists.txt Selects C++23 for the example.
components/​esp32-ethernet-kit/​example/​CMakeLists.txt Selects C++23 for the example.
components/​esp32-p4-eth/​example/​CMakeLists.txt Selects C++23 for the example.
components/​esp32-p4-function-ev-board/​example/​CMakeLists.txt Selects C++23 for the example.
components/​esp32-p4-nano/​example/​CMakeLists.txt Selects C++23 for the example.
components/​esp32-timer-cam/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ethernet/​example/​CMakeLists.txt Selects C++23 for the example.
components/​event_manager/​example/​CMakeLists.txt Selects C++23 for the example.
components/​expressive_eyes/​example/​CMakeLists.txt Selects C++23 for the example.
components/​file_system/​example/​CMakeLists.txt Selects C++23 for the example.
components/​filters/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ft5x06/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ftp/​example/​CMakeLists.txt Selects C++23 for the example.
components/​gfps_service/​example/​CMakeLists.txt Selects C++23 for the example.
components/​gps/​example/​CMakeLists.txt Selects C++23 for the example.
components/​gt911/​example/​CMakeLists.txt Selects C++23 for the example.
components/​hid_service/​example/​CMakeLists.txt Selects C++23 for the example.
components/​hid-rp/​example/​CMakeLists.txt Selects C++23 for the example.
components/​hid-rp/​test/​hid_rp_3dconnexion_host_test.cpp Updates the documented test command.
components/​hid-rp/​test/​hid_rp_gamepad_host_test.cpp Updates the documented test command.
components/​hid-rp/​test/​hid_rp_report_map_host_test.cpp Updates the documented test command.
components/​i2c/​example/​CMakeLists.txt Selects C++23 for the example.
components/​icm20948/​example/​CMakeLists.txt Selects C++23 for the example.
components/​icm42607/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ina226/​example/​CMakeLists.txt Selects C++23 for the example.
components/​interrupt/​example/​CMakeLists.txt Selects C++23 for the example.
components/​iperf_menu/​example/​CMakeLists.txt Selects C++23 for the example.
components/​joystick/​example/​CMakeLists.txt Selects C++23 for the example.
components/​kts1622/​example/​CMakeLists.txt Selects C++23 for the example.
components/​led/​example/​CMakeLists.txt Selects C++23 for the example.
components/​led_strip/​example/​CMakeLists.txt Selects C++23 for the example.
components/​lilygo-t5-47/​example/​CMakeLists.txt Selects C++23 for the example.
components/​logger/​example/​CMakeLists.txt Selects C++23 for the example.
components/​lp5817/​example/​CMakeLists.txt Selects C++23 for the example.
components/​lsm6dso/​example/​CMakeLists.txt Selects C++23 for the example.
components/​m5stack-cardputer/​example/​CMakeLists.txt Selects C++23 for the example.
components/​m5stack-tab5/​example/​CMakeLists.txt Selects C++23 for the example.
components/​math/​example/​CMakeLists.txt Selects C++23 for the example.
components/​matouch-rotary-display/​example/​CMakeLists.txt Selects C++23 for the example.
components/​max1704x/​example/​CMakeLists.txt Selects C++23 for the example.
components/​mcp23x17/​example/​CMakeLists.txt Selects C++23 for the example.
components/​mcp266/​example/​CMakeLists.txt Selects C++23 for the example.
components/​mcp266/​webapp_example/​CMakeLists.txt Selects C++23 for the webapp example.
components/​mcp266/​test/​mcp266_host_test.cpp Updates the documented test command.
components/​mcp266/​test/​mcp266_protocol_host_test.cpp Updates the documented test command.
components/​meshtastic/​example/​CMakeLists.txt Selects C++23 for the example.
components/​monitor/​example/​CMakeLists.txt Selects C++23 for the example.
components/​monitor/​test/​monitor_host_test.cpp Updates the documented test command.
components/​motorgo-axis/​example/​CMakeLists.txt Selects C++23 for the example.
components/​motorgo-mini/​example/​CMakeLists.txt Selects C++23 for the example.
components/​motorgo-plink/​example/​CMakeLists.txt Selects C++23 for the example.
components/​mt6701/​example/​CMakeLists.txt Selects C++23 for the example.
components/​neopixel/​example/​CMakeLists.txt Selects C++23 for the example.
components/​nvs/​example/​CMakeLists.txt Selects C++23 for the example.
components/​odrive_ascii/​example/​CMakeLists.txt Selects C++23 for the example.
components/​odrive_native/​example/​CMakeLists.txt Selects C++23 for the example.
components/​odrive_native/​usb_example/​CMakeLists.txt Selects C++23 for the USB example.
components/​odrive_native/​test/​odrive_native_host_test.cpp Updates the documented test command.
components/​odrive_native/​test/​odrive_native_stream_test.cpp Updates the documented test command.
components/​odrive_native/​interop/​README.md Updates the documented compiler command.
components/​odrive_native/​interop/​odrive_native_interop_device.cpp Updates embedded build instructions.
components/​odrive_native/​interop/​run.sh Documents a C++23 compiler requirement.
components/​odrive_native/​interop/​run_interop.sh Compiles interop targets as C++23.
components/​odrive_native/​python/​tests/​test_odrive.py Compiles the test device as C++23.
components/​ota/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ota/​README.md Updates requirements and test command.
components/​ota/​test/​ota_protocol_host_test.cpp Updates the documented test command.
components/​pca9535/​example/​CMakeLists.txt Selects C++23 for the example.
components/​pcf85063/​example/​CMakeLists.txt Selects C++23 for the example.
components/​pi4ioe5v/​example/​CMakeLists.txt Selects C++23 for the example.
components/​pid/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ping/​example/​CMakeLists.txt Selects C++23 for the example.
components/​provisioning/​example/​CMakeLists.txt Selects C++23 for the example.
components/​qmi8658/​example/​CMakeLists.txt Selects C++23 for the example.
components/​qtpy/​example/​CMakeLists.txt Selects C++23 for the example.
components/​qwiicnes/​example/​CMakeLists.txt Selects C++23 for the example.
components/​reflect_cpp/​README.md Documents the C++23 requirement.
components/​remote_debug/​example/​CMakeLists.txt Selects C++23 for the example.
components/​rmt/​example/​CMakeLists.txt Selects C++23 for the example.
components/​rtps/​example/​CMakeLists.txt Selects C++23 for the embedded example.
components/​rtps/​example/​pc/​CMakeLists.txt Requires C++23 for the host target.
components/​rtsp/​example/​CMakeLists.txt Selects C++23 for the example.
components/​runqueue/​example/​CMakeLists.txt Selects C++23 for the example.
components/​rx8130ce/​example/​CMakeLists.txt Selects C++23 for the example.
components/​sdcard/​example/​CMakeLists.txt Selects C++23 for the example.
components/​seeed-studio-round-display/​example/​CMakeLists.txt Selects C++23 for the example.
components/​serialization/​example/​CMakeLists.txt Selects C++23 for the example.
components/​smartpanlee-sc01-plus/​example/​CMakeLists.txt Selects C++23 for the example.
components/​socket/​example/​CMakeLists.txt Selects C++23 for the example.
components/​spi/​example/​CMakeLists.txt Selects C++23 for the example.
components/​st25dv/​example/​CMakeLists.txt Selects C++23 for the example.
components/​state_machine/​example/​CMakeLists.txt Selects C++23 for the example.
components/​stream_frame/​example/​CMakeLists.txt Selects C++23 for the example.
components/​stream_frame/​include/​stream_frame.hpp Updates the documented library level.
components/​stream_frame/​README.md Updates requirements and test command.
components/​stream_frame/​test/​stream_frame_host_test.cpp Updates the documented test command.
components/​switch_pro/​example/​CMakeLists.txt Selects C++23 for the example.
components/​sx126x/​example/​CMakeLists.txt Selects C++23 for the example.
components/​system/​example/​CMakeLists.txt Selects C++23 before project setup.
components/​system/​test/​system_host_test.cpp Updates the documented test command.
components/​t-deck/​example/​CMakeLists.txt Selects C++23 for the example.
components/​t-dongle-s3/​example/​CMakeLists.txt Selects C++23 for the example.
components/​t_keyboard/​example/​CMakeLists.txt Selects C++23 for the example.
components/​tabulate/​example/​CMakeLists.txt Selects C++23 for the example.
components/​task/​example/​CMakeLists.txt Selects C++23 for the example.
components/​telemetry/​example/​CMakeLists.txt Selects C++23 before project setup.
components/​thermistor/​example/​CMakeLists.txt Selects C++23 for the example.
components/​thread_pool/​example/​CMakeLists.txt Selects C++23 before project setup.
components/​timer/​example/​CMakeLists.txt Selects C++23 for the example.
components/​tla2528/​example/​CMakeLists.txt Selects C++23 for the example.
components/​touch/​example/​CMakeLists.txt Selects C++23 for the example.
components/​trajectory_planner/​example/​CMakeLists.txt Selects C++23 for the example.
components/​tt21100/​example/​CMakeLists.txt Selects C++23 for the example.
components/​twai/​example/​CMakeLists.txt Selects C++23 for the example.
components/​usb_device/​example/​CMakeLists.txt Selects C++23 for the example.
components/​usb_device/​msc_example/​CMakeLists.txt Selects C++23 for the MSC example.
components/​usb_device/​xinput_example/​CMakeLists.txt Selects C++23 for the XInput example.
components/​usb_device/​test/​xinput_host_test.cpp Updates the documented test command.
components/​usb_host/​example/​CMakeLists.txt Selects C++23 for the example.
components/​usb_host/​tab5_example/​CMakeLists.txt Selects C++23 for the Tab5 example.
components/​vl53l/​example/​CMakeLists.txt Selects C++23 for the example.
components/​wdi/​ble_central_example/​CMakeLists.txt Selects C++23 for the BLE central example.
components/​wdi/​ble_example/​CMakeLists.txt Selects C++23 for the BLE example.
components/​wdi/​usb_example/​CMakeLists.txt Selects C++23 for the USB example.
components/​wdi/​usb_host_example/​CMakeLists.txt Selects C++23 for the USB host example.
components/​wdi/​include/​wdi.hpp Updates the documented library level.
components/​wdi/​include/​wdi_host.hpp Updates the documented library level.
components/​wdi/​README.md Updates requirements and test commands.
components/​wdi/​test/​wdi_device_host_test.cpp Updates the documented test command.
components/​wdi/​test/​wdi_hid_host_test.cpp Updates the documented test command.
components/​wdi/​test/​wdi_host_host_test.cpp Updates the documented test command.
components/​wdi/​test/​wdi_protocol_host_test.cpp Updates the documented test command.
components/​wifi/​example/​CMakeLists.txt Selects C++23 for the example.
components/​wrover-kit/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ws-s3-geek/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ws-s3-lcd-1-47/​example/​CMakeLists.txt Selects C++23 for the example.
components/​ws-s3-touch/​example/​CMakeLists.txt Selects C++23 for the example.
components/​xiao-esp32s3-sense/​example/​CMakeLists.txt Selects C++23 for the example.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

project(adc_example)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
(automatic with `espp::Twai`, whose `on_receive` runs in its own task).

The wire core (`include/detail/canopen_core.hpp`) is host-buildable pure C++20
The wire core (`include/detail/canopen_core.hpp`) is host-buildable pure C++23
path arg), registers a small ODrive-like tree on an `OdriveNativeCore`, and runs
the serve loop: stream bytes → `StreamDeframer` → `process_bytes` → `stream_frame`
→ write. Uses only the host-buildable `detail/` headers (plain `c++ -std=c++20`,
→ write. Uses only the host-buildable `detail/` headers (plain `c++ -std=c++23`,
// the spec.
//
// The class depends only on the C++20 standard library and the WDI protocol core
// The class depends only on the C++23 standard library and the WDI protocol core
logic (CRC16, packet building, reply validation, big-endian codecs) lives in
``espp::detail`` inside ``include/detail/basicmicro_core.hpp``, a
host-buildable core that depends only on the C++20 standard library and is
host-buildable core that depends only on the C++23 standard library and is
@owenpkent

Copy link
Copy Markdown
Contributor Author

Verified the example CMakeLists.txt change against real IDF builds (v5.5.1, the CI version, and v6.0.2), so the earlier hedge in the description is gone.

  • hid-rp/example builds cleanly for esp32s3 on both versions.
  • 134 of the 143 examples set CMAKE_CXX_STANDARD after project(), which in IDF is after every component target exists, so it emits no -std= flag at all. The compile line carries only IDF's own -std=gnu++2b (5.5.1) / -std=gnu++26 (6.0.2).
  • The 9 that set it before project() get -std=gnu++23 -std=gnu++2b; the last flag wins, so IDF's still applies.

So on device the sources were already compiling at C++23 or newer; the 20 was only misleading. The CMake change is purely for consistency. Workflows need a maintainer approval since the PR is from a fork.

@finger563
finger563 merged commit 1ae5fda into esp-cpp:main Oct 12, 2026
176 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants