Skip to content

Support noexcept callables in function_traits - #3322

Merged
ahcorde merged 1 commit into
ros2:rollingfrom
KR-Ravindra:fix/function-traits-noexcept
Oct 14, 2026
Merged

ahcorde merged 1 commit into
ros2:rollingfrom
KR-Ravindra:fix/function-traits-noexcept

Conversation

@KR-Ravindra

Copy link
Copy Markdown
Contributor

Description

Fixes #2654

Problem

Since C++17, noexcept is part of the function type. function_traits has no specializations for noexcept callables, so they fall through to the primary template, which then fails on &FunctionT::operator(). Callbacks like a noexcept free function, [](int) noexcept {}, or std::bind(&C::cb, this, _1) with void cb(int) noexcept don't compile when passed to APIs that use function_traits.

Fix

This adds noexcept specializations that forward to the existing ones. They cover free functions, function pointers, const call operators (lambdas), and std::bind of noexcept methods (const and non-const) and free functions, in every standard-library branch the file already handles. Callbacks are still not required to be noexcept, per the discussion in the issue.

How tested

There's a new TestFunctionTraits.noexcept_callables gtest in test_function_traits.cpp. I couldn't run colcon test locally, so I compiled and ran test_function_traits.cpp on its own against the header (it only needs the standard library):

  • Apple clang 21 / libc++ (macOS): 8/8 pass. With the current header, it fails to compile on every noexcept case.
  • GCC 14 / libstdc++ (gcc:14 container), -Wall -Wextra -Werror: 8/8 pass, against 25 compile errors with the current header.
  • The MSVC branch mirrors the existing one but is untested locally, so please rely on the Windows CI for it.
  • cpplint with the ament line length is clean. I haven't run ament_uncrustify.

Is this user-facing behavior change?

Yes: noexcept callables can now be used as callbacks.

Did you use Generative AI?

Yes. The change, tests and this description were prepared with Claude Code (Claude Opus 5.5), an AI agent operated by KR-Ravindra, who reviewed and tested it. The agent is pointed only at issues maintainers have confirmed and problems he has hit, not at producing contributions.

noexcept has been part of the function type since C++17, so noexcept free functions, function pointers, lambdas and std::bind of noexcept functions or methods fell through to the primary function_traits template and failed to compile (e.g. as timer or subscription callbacks). Add noexcept specializations that forward to the existing ones.

Fixes ros2#2654

Signed-off-by: KR Ravindra <42912207+KR-Ravindra@users.noreply.github.com>
@KR-Ravindra
KR-Ravindra marked this pull request as ready for review October 12, 2026 00:37
@github-actions

Copy link
Copy Markdown

ABI Compliance Check

✅ Verdict: compatible

Library Verdict Summary
libcomponent_manager.so ✅ compatible No ABI changes detected.
librclcpp.so ✅ compatible No ABI changes detected.
librclcpp_action.so ✅ compatible No ABI changes detected.
librclcpp_lifecycle.so ✅ compatible No ABI changes detected.
✅ libcomponent_manager.so — full abidiff report

Compared:

  • Base: lib-base/libcomponent_manager.so
  • Head: lib-pr/libcomponent_manager.so @ 9485c0f
(empty report — no differences printed by abidiff)
✅ librclcpp.so — full abidiff report

Compared:

  • Base: lib-base/librclcpp.so
  • Head: lib-pr/librclcpp.so @ 9485c0f
(empty report — no differences printed by abidiff)
✅ librclcpp_action.so — full abidiff report

Compared:

  • Base: lib-base/librclcpp_action.so
  • Head: lib-pr/librclcpp_action.so @ 9485c0f
(empty report — no differences printed by abidiff)
✅ librclcpp_lifecycle.so — full abidiff report

Compared:

  • Base: lib-base/librclcpp_lifecycle.so
  • Head: lib-pr/librclcpp_lifecycle.so @ 9485c0f
(empty report — no differences printed by abidiff)

Updated for commit 9485c0f · suppressions: /home/runner/work/_temp/ros2-abi-suppressions.txt

@fujitatomoya fujitatomoya left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

lgtm with green CI.

@fujitatomoya

fujitatomoya commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Pulls: #3322
Gist: https://github.com/proxy/gist.githubusercontent.com/fujitatomoya/00c2df441c1c534bc665658a5962ab38/raw/6731d30fd44b870565de68785845495c98400b83/ros2.repos
BUILD args: --packages-above-and-dependencies rclcpp
TEST args: --packages-above rclcpp
ROS Distro: rolling
Job: ci_launcher
ci_launcher ran: https://ci.ros2.org/job/ci_launcher/20753

  • Linux Build Status
  • Linux-aarch64 Build Status
  • Linux-rhel Build Status
  • Windows Build Status

@ahcorde
ahcorde merged commit a23a39f into ros2:rolling Oct 14, 2026
10 of 11 checks passed
mjcarroll pushed a commit that referenced this pull request Oct 20, 2026
The noexcept specializations added in #3322 make the rosdoc2
documentation build fail: Sphinx's C++ domain hits an internal
AssertionError while resolving references in the function_traits
specializations. Wrap the noexcept variants in \cond/\endcond so Doxygen
skips them. They mirror the documented non-noexcept specializations, and
the compiled code is unchanged.

Signed-off-by: R Kent James <kent@caspia.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow Node functionality to use methods with noexcept modifiers.

3 participants