

A hole in Clang's `-Wsuggest-override` – Arthur O'Dwyer – Stuff mostly about C++
source link: https://quuxplusone.github.io/blog/2021/02/19/virtual-final-silences-override-warning/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

A hole in Clang’s -Wsuggest-override
Consider this code (Godbolt):
struct B {
virtual int f() = 0;
virtual int g() = 0;
};
struct C : B {
int f() override;
virtual int g() final; // overrides
virtual int h() final; // doesn't
};
In any real codebase, you should never ever use virtual
and final
together like this.
Use only
virtual
(preferably with=0
) in root classes.Use only
override
orfinal
(withoutvirtual
) in non-root classes.
So this code is extremely unrealistic.
However, I was surprised that Clang’s -Wsuggest-override
diagnostic is not
smart enough to complain here. The syntax of this code fails to indicate its meaning —
obviously, because C::g()
and C::h()
have the same syntax but different meanings.
Therefore, the compiler really ought to discourage the programmer from writing
this “ambiguous” syntax.
By the way, kudos to Clang for implementing -Wsuggest-override
at all.
I recommend that everybody turn it on immediately!
-Wall
includes-Winconsistent-missing-override
, which warns within classes that are already usingoverride
in some places but not others.-Wsuggest-override
is more advanced; it diagnoses missingoverride
keywords even in classes that don’t already use it.
I think I want a diagnostic spelled something like -Wsuggest-omit-virtual
.
Stylistically, the virtual
keyword should be used only on roots; the absence of virtual
unambiguously signals the intentional absence of root-ness, in the same way that
the absence of override
/final
(in modern code) unambiguously signals
the intentional absence of overriding-ness.
The proper shape of class C
is thus:
struct C : B {
int f() override;
int g() final; // overrides
virtual int h() final; // doesn't
};
g
’s syntax now differs from h
’s, which is appropriate, because g
’s meaning
differs from h
’s.
The use of virtual
and final
together in h
’s signature indicates that
h
is both a root and a leaf — highly unrealistic, but technically possible!
See also:
- “Two musings on the design of compiler warnings” (2020-09-02)
Recommend
-
9
Thoughts on “Does GPT-2 Know Your Phone Number?”
-
14
decltype of a non-static member
-
8
Don’t blindly prefer emplace_back to push_back
-
14
C’s removal of gets could have been done bette...
-
15
Playing Castlequest (1980), Part 2
-
6
Playing Castlequest (1980), Part 1
-
15
Observations on Castlequest’s code
-
7
Next week, April 18 through 24, the Gathering 4 Gardner is hosting a week-long Celebration of Mind, featuring three brief presentations per day, every day. The s...
-
11
P2266’s interaction with decltype(auto)
-
14
An interview with Arthur O’Dwyer
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK