isocpp / isocpp/CppCoreGuidelines

C.21 appears to mandate the Rule of Five -- is that desirable?

Open
#2,335 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
CSS
Stars
45.3k
Forks
5.6k
PR merge metrics
No merged PRs in 30d

Description

See also #2164 where this issue is creating false positives in Guidelines checkers such as clang-tidy.

Problem

C.21 mandates the Rule of Five:

C.21: If you define or =delete any copy, move, or destructor function, define or =delete them all

[...]

Enforcement

(Simple) A class should have a declaration (even a =delete one) for either all or none of the copy/move/destructor functions.

Is that too strong?

  • Yes, this will catch some errors, as noted: "to avoid unwanted effects like turning all potential moves into more expensive copies, or making a class move-only." That's good.
  • But this will also require programmers to write redundant boilerplate for classes that don't need it, such as classes that have user-written copy operations where move cannot be more efficient than copy and the programmer knows that writing only copy will cause move to be treated as copy for their type and know that's okay. Programmers hate being told to make code changes that they know don't change meaning just to satisfy a tool, and it's the kind of thing that causes them to disable a rule as noisy / low-value.

Note: The current rule and Enforcement would flag every pre-C++11 class with a user-defined copy operation.

One potential suggestion

The main noise seems to come from requiring explicit move operations. One change that could address #2164 and pre-C++11 types and most of the required-boilerplate cases would be to not require writing out move operations. Something like this:

C.21: If you define or =delete any copy, move, or destructor function, define or =delete all copy and destructor operations

[...]

Enforcement

(Simple) A class should have a declaration (even a =delete one) for all copy/destructor functions if any copy/move/destructor function is user-declared.

We could also add a note along the lines of "and if you write a copy operation check whether you should also write a more-efficient move operation, to avoid turning all potential moves into more expensive copies" -- as a Note here, or as a separate guideline.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the current C.21 rule and enforcement text, then review the related discussion in #2164 and the cited clang-tidy false positives. Compare the proposed wording with the documented rationale and pre-C++11 behavior. Done means a maintainer-approved decision and updated guideline text, if a change is accepted.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.