C++ Logo

std-proposals

Advanced search

Re: [std-proposals] !override

From: Paul Fee <paul.f.fee_at_[hidden]>
Date: Fri, 11 Nov 2022 09:23:05 +0000
I agree, we don't need to proceed further with this suggestion. The
feedback given on this thread illustrates alternative approaches that exist
today, so no need to add to language complexity.

On Fri, Nov 11, 2022 at 12:14 AM Jason C <jason.cipriani_at_[hidden]> wrote:

> I don't think this makes sense as a language feature.
>
> The goal seems to be to catch and/or prevent accidentally overridden
> methods. That makes more sense as a compiler warning. GCC at least already
> implements that:
>
> gcc -Wsuggest-override
>
> Will warn if a method without an "override" keyword is in fact an override.
>
> gcc --Wsuggest-override -Werror=suggest-override
>
> Will produce an error in the same case, which is exactly the end effect
> that you're looking for.
>
> For MS's CL compiler (MSVC) you can enable warning C26433 (or treat it as
> an error).
>
> Warnings can always be enabled per file, in both compilers.
>
> So this doesn't really need to be in the language.
>
> Jason
>
>
>
> On Mon, Nov 7, 2022 at 11:24 AM Paul Fee via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> Hello,
>>
>> 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. When refactoring large codebases, one
>> may wish to make an isolated API change but inadvertently changes code
>> that's part of a class hierarchy. Some additional specifiers may allow
>> developers to proceed with caution, protecting them before breaking
>> functionality.
>>
>> Example:
>>
>> struct Base
>> {
>> virtual bool state() { return false; }
>> };
>>
>> struct Derived : public Base
>> {
>> bool state() { return s; }
>> private:
>> bool s = false;
>> }
>>
>> One may opt to refactor state() to make it a const method, without
>> noticing there's also an implementation in the base class as "virtual" is
>> only necessary in the base class. Such a change should be applied
>> consistently throughout the hierarchy. I'd like the compiler to confirm
>> that the member function does NOT override a base class function, then I'd
>> be able to follow up with broader refactoring knowing the impact of the
>> change is limited to just one class. The final specifier means I don't
>> need to look further down the class hierarchy, but I don't have a specifier
>> that ensures I don't need to look up the hierarchy.
>>
>> Step 1: If this still compiles, then we know there'll be no surprises
>> when changing the API.
>> struct Derived final : public Base
>> {
>> bool state() !override { return s; }
>> private:
>> bool s = false;
>> }
>>
>> Step 2: state function signature can be safely changed.
>> struct Derived final : public Base
>> {
>> bool state() const !override { return s; }
>> private:
>> bool s = false;
>> }
>>
>> Here !override is use as example syntax, but that was just to illustrate
>> the idea. When refactoring, step 1 would fail to compile because
>> Derived::state() does override Base::state(). This alerts the developer to
>> the danger of only changing the derived class.
>>
>> 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
>>
>> Thanks,
>> Paul
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>

Received on 2022-11-11 09:23:17