C++ Logo


Advanced search

Re: [std-proposals] !override

From: Paul Fee <paul.f.fee_at_[hidden]>
Date: Mon, 7 Nov 2022 22:57:02 +0000
Thanks to all for your replies.

My only need for this is during refactoring. You've collectively given me
enough options to address my issue without additions to C++, so we needn't
go further.

The GCC -Werror=suggest-override disappeared from their manual after GCC 9,
though it still works with GCC 12.

My suggestion derived from my current use of "final". I often place it on
a class (despite core-guidelines C.139) to prove that there are no derived
classes. I'm then free to remove redundant use of virtual, which may for
example allow the virtual destructor to evaporate, allowing application of
the rule-of-zero.

Another refactor is to mark copy constructors "= delete", to prove they're
never used. This allows a redundant user-declared implementation to be
removed without fear of impacting behaviour. Sometimes I encounter code
that replicates what the language defaults already perform, but it's useful
to have the compiler confirm that the code being removed was already dead

These approaches help ensure refactors don't change behaviour. I had
wanted more ways of getting the compiler to confirm my assumptions before
touching the code. Your collective answers have provided me with them.

Thank you,

On Mon, Nov 7, 2022 at 6:39 PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>

> On Mon, Nov 7, 2022 at 11:24 AM Paul Fee via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>> The "final" and "override" specifiers can be useful to ensure code using
>> inheritance is implemented as expected. However there are some gaps where
>> I find some features lacking, I can't express some approaches nor get the
>> compiler to confirm my assumptions. [...]
>> Would it be reasonable to enhance the set of specifiers so that more
>> scenarios can be expressed, allowing the compiler to confirm if the
>> developer's assumptions are correct? For example:
>> * function must/must not override a base class function
>> * function must/must not be part of a group of overloads
>> * function must/must not be virtual
> All of these scenarios are handled, as long as you follow the simple best
> practices for OOP code in C++11-and-later. I believe the Core Guidelines
> cover this
> <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-override>,
> as does Scott Meyers and of course myself. ;)
> The rules are:
> - Use `virtual` (only) in base classes.
> - Use `override` (only) in derived classes.
> - That's all.
> Your specific scenarios:
> - This function must override a base-class function: That's just `int f()
> override;`. Foolproof even if you don't follow the guidelines.
> - This function must NOT override a base-class function: That's `int
> f();`. Compile with `-Werror=suggest-override`.
> - This function must be virtual: That's either `virtual int f();` or `int
> f() override`, depending on if you're introducing or overriding `f`.
> Compile with `-Werror=suggest-override`.
> - This function must not be virtual: That's `int f();` Compile with
> `-Werror=suggest-override`.
> - This function must (not) be part of a group of overloads: That's not
> something you want in C++. *Every* function is part of an overload set of
> *some* cardinality; sometimes that cardinality just happens to be 1. Titus
> Winters says <https://www.youtube.com/watch?v=xTdeZ4MxbKo&t=653s>, "The
> unit of API design is the overload set."
> If you really want to segregate public (overloadable) APIs from private
> (overridable) implementations, may I suggest the Non-Virtual Interface
> Idiom. :) I use it exclusively, and it's great. I have some training
> material on it, and it was also covered in Jon Kalb's "Back to Basics:
> Object-Oriented Programming,"
> <https://www.youtube.com/watch?v=32tDTD9UJCE> among other places.
> –Arthur

Received on 2022-11-07 22:57:14