isocpp / isocpp/CppCoreGuidelines

ES.63 not justifiable as stated and clashes with P.1 and P.3

Open
#2,336 4 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

Rule ES.63: Don't slice is worded very strongly and decisively. It claims slicing is (almost always) undesirable and inappropriate: In all contexts, for all purposes. The motivation given, however, is that this "most often leads to errors".

So, my first point is that the rule itself concedes that this does not always lead to errors; and that we (or the rule authors) do not have a general argument about an arbitrary slicing scenario leading to errors, in itself. That is, given class B : public A { /*...*/ } and result_type foo(A), I do not believe we can show that calling foo(some_B) is problematic, unless we make significant assumptions about A and B. And the rule can only stand when qualified by these assumptions.

The second point regards the expression of intent, rule P.3.

When a programmer says class B : public A, they are saying that "An object of type B is, in particular, an object of type A - and can be treated as such" (in other words, the use of public inheritance implies, or strongly insinuates, that the Liskov Substitution Principle applies.) An object of type A can be passed to a function which takes a parameter of type A, by value. Claiming that slicing is essentially forbidden means that we must ignore the expressed intent of the public inheritance, or rather, than we use public inheritance despite not having its actual intent.

If slicing is problematic for some class B : public A, then - why should B publicly inherit A? The inheritance could be protected, or private. That way, the programmer actually tells the compiler (and other programmers) whether the A making up B can or can't be sliced. But - that's a bit of a facetious point: We know such a convention is not what most programmers use in practice - because of convenience. If you inherit private or protected, you have to explicitly make available each and every bit of A again in B, which is quite tedious. So, the lazy thing to do is to just inherit publicly and rely on people ignoring the public inheritance: "I know I said my B is an A, but, come on, don't take it seriously... pretend my class is mis-defined and be extra-careful yourself".

I am not suggesting, that the guidelines switch position entirely, and demand that everyone change the way they code, and only use protected and private inheritance when slicing is problematic. But - ES.63 as it stands essentially forces people to adopt a broken interpretation of public inheritance - to ignore the expressed intent.

For these two reasons, I claim that the guideline should be relaxed from "don't slice" to something like "carefully consider the legitimacy of slicing" (this doesn't have to be the exact phrasing of course); and that the rule mention the potential pitfalls explicitly, but also remind readers about the meaning of public inhertance, suggesting that they also consider the possibility of private/proctected inheritance if they are the class authors. The cases of zero-size / no-data-members objects can then be mentioned more briefly as an example of a legitimate use of slicing.

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 with the ES.63 section in CppCoreGuidelines.md and compare its wording with the referenced P.1 and P.3 guidance. Review the current rationale and examples, then propose revised text that addresses the stated concerns about legitimate slicing and public inheritance. Done means the guideline's strength, pitfalls, and inheritance implications are clearly reconciled.

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
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.