C++#
Warning
Under Construction
References#
Follow the guidelines below if a rule is not defined on this page.
- https://docs.ros.org/en/humble/Contributing/Code-Style-Language-Versions.html
- https://www.autosar.org/fileadmin/standards/adaptive/22-11/AUTOSAR_RS_CPP14Guidelines.pdf
- https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
Also, it is encouraged to apply Clang-Tidy to each file. For the usage, see Applying Clang-Tidy to ROS packages.
Note that not all rules are covered by Clang-Tidy.
Style rules#
Include header files in the defined order (required, partially automated)#
Rationale#
- Due to indirect dependencies, the include system of C++ makes different behaviors if the header order is different.
- To reduce unintended bugs, local header files should come first.
Reference#
Example#
Include the headers in the following order:
- Main module header
- Local package headers
- Other package headers
- Message headers
- Boost headers
- C system headers
- C++ system headers
// Compliant
#include "my_header.hpp"
#include "my_package/foo.hpp"
#include <package1/foo.hpp>
#include <package2/bar.hpp>
#include <std_msgs/msg/header.hpp>
#include <iostream>
#include <vector>
If you use ""
and <>
properly, ClangFormat
in pre-commit
sorts headers automatically.
Do not define macros between #include
lines because it prevents automatic sorting.
// Non-compliant
#include <package1/foo.hpp>
#include <package2/bar.hpp>
#define EIGEN_MPL2_ONLY
#include "my_header.hpp"
#include "my_package/foo.hpp"
#include <Eigen/Core>
#include <std_msgs/msg/header.hpp>
#include <iostream>
#include <vector>
Instead, define macros before #include
lines.
// Compliant
#define EIGEN_MPL2_ONLY
#include "my_header.hpp"
#include "my_package/foo.hpp"
#include <Eigen/Core>
#include <package1/foo.hpp>
#include <package2/bar.hpp>
#include <std_msgs/msg/header.hpp>
#include <iostream>
#include <vector>
If there are any reasons for defining macros at a specific position, write a comment before the macro.
// Compliant
#include "my_header.hpp"
#include "my_package/foo.hpp"
#include <package1/foo.hpp>
#include <package2/bar.hpp>
#include <std_msgs/msg/header.hpp>
#include <iostream>
#include <vector>
// For the foo bar reason, the FOO_MACRO must be defined here.
#define FOO_MACRO
#include <foo/bar.hpp>
Use lower snake case for function names (required, partially automated)#
Rationale#
- It is consistent with the C++ standard library.
- It is consistent with other programming languages such as Python and Rust.
Exception#
- For member functions of classes inherited from external project classes such as Qt, follow that naming convention.
Reference#
Example#
void function_name()
{
}
Use upper camel case for enum names (required, partially automated)#
Rationale#
- It is consistent with ROS 2 core packages.
Exception#
- Enums defined in the
rosidl
file can use other naming conventions.
Reference#
- http://wiki.ros.org/CppStyleGuide (Refer to "15. Enumerations")
Example#
enum class Color
{
Red, Green, Blue
}
Use lower snake case for constant names (required, partially automated)#
Rationale#
- It is consistent with ROS 2 core packages.
- It is consistent with
std::numbers
.
Exception#
- Constants defined in the
rosidl
file can use other naming conventions.
Reference#
Example#
constexpr double gravity = 9.80665;
Count acronyms and contractions of compound words as one word (required, partially automated)#
Rationale#
- To clarify the boundaries of words when acronyms are consecutive.
Reference#
Example#
class RosApi;
RosApi ros_api;
Do not use the auto keywords with Eigen's expressions (required)#
Rationale#
- Avoid using auto with
Eigen::Matrix
orEigen::Vector
variables, as it can lead to bugs.
Reference#
Use RCLCPP_* (e.g. RCLCPP_INFO) macros instead of printf or std::cout for logging (required)#
Rationale#
- Reasons include the following:
- It allows for consistent log level management. For instance, with RCLCPP_* macros, you can simply set --log_level to adjust the log level uniformly across the application.
- You can standardize the format using RCUTILS_CONSOLE_OUTPUT_FORMAT.
- With RCLCPP_* macros, logs are automatically recorded to /rosout. These logs can be saved to a rosbag, which can then be replayed to review the log data.