4

This is a design question, let's have a simple method:

virtual void Test() { };

We can override it the same way, or even not specifying virtual at all probably, but then there's this override keyword, which makes the compiler check it is actually overriding something, which is useful, but it needs to be written like this:

void Test() override { };

To me this makes no sense, since I'd edit literally thousands of these methods, and as it is now, the editing would be just too clumsy to spend the time with. So what is the logic behind placing the override after, since it could be much easier and to me generally better like this:

override void Test() { };
cigien
  • 57,834
  • 11
  • 73
  • 112
mrzacek mrzacek
  • 308
  • 2
  • 12
  • I'm curious why `virtual` is in front in the first place. Every other function modifiers go at the end of the declaration. – François Andrieux Oct 13 '20 at 21:00
  • Actually to me virtual is pretty much the most important one, so it makes lots of sense to put it in there. But I get your point. Anyways I think inline and stuff like that goes in the beginning too. – mrzacek mrzacek Oct 13 '20 at 21:02

1 Answers1

4

virtual was introduced right at the beginning of C++ as a keyword. This means you can't use it as a variable name, a class name, a function name, and so on.

override came much later on. In order that its introduction in C++11 didn't break existing code, it doesn't quite attain the status of a keyword; rather it's called an identifier with special meaning. final is similar.

Its curious positioning is specified by the language grammar: an example where allowing it to be at the beginning would be a breaking change is

override :: foo bar()

where override::foo must be a qualified return type of the function bar() rather than an overrider with a explicitly global return type ::foo (Acknowledge @BenVoigt.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Well, that's true, but it quite doesn't explain it. It cannot break existing code, since it didn't exist in the first place :) – mrzacek mrzacek Oct 13 '20 at 21:03
  • 5
    @mrzacekmrzacek If `override` became a keyword, then you'd no longer be able to use `override` as a variable name, and that's a problem. – Bathsheba Oct 13 '20 at 21:03
  • 3
    @mrzacekmrzacek Consider that code from previous versions of C++ could use `override` as an identifier. For example `override foo();` could be a function that returns an object of type `override`. – François Andrieux Oct 13 '20 at 21:04
  • Aaaaha, understood. On the other hand, can you even do that with virtual functions? – mrzacek mrzacek Oct 13 '20 at 21:04
  • It is true that `virtual` is a keyword while `override` is an "identifier with special meaning". But I'm not sure it explains the difference in placement. `const` is a keyword and is placed at the end of the declaration. Obviously it would be difficult to have it at the start (it would be ambiguous with the return type) but it shows that being a or not being a keyword is not a limiting factor on token placement. – François Andrieux Oct 13 '20 at 21:05
  • 1
    @mrzacekmrzacek There has never been a standard version of C++ where `virtual` was not a keyword so there could not been any existing code using `virtual` as an identifier that could have been broken by the inclusion of `virtual` as a keyword. – François Andrieux Oct 13 '20 at 21:05
  • @FrançoisAndrieux A `const` at the beginning of a member function has a different meaning (`const` return type) to the one at the end (implicit `this` is `const`). That said, I can't think of an example where override at the beginning certainly is a breaking change. I'll have to get my grammar book out ;-) – Bathsheba Oct 13 '20 at 21:09
  • I've weakened the last sentence substantially. I can't think of a counter-example. Putting it at the beginning would create some substantial grammar changes which might upset compiler writers, but that doesn't normally seem to stop the standards committee! – Bathsheba Oct 13 '20 at 21:18
  • 1
    @cigien: Example of existing code that would be broken: `override :: foo bar()`. Is that a qualified return type (`override::foo`), or an overrider with a explicitly global return type `::foo` ? – Ben Voigt Oct 13 '20 at 21:19
  • @BenVoigt Yes, that's a good example :) – cigien Oct 13 '20 at 21:21
  • @Bathsheba This is a dupe (which is a little surprising). Anyway, it links to a paper, and it seems the motivation was to avoid that position in a declarator becoming too crowded :) – cigien Oct 13 '20 at 21:22
  • @cigien: Yep that was a typo, thanks for pointing it out. Now corrected. – Ben Voigt Oct 13 '20 at 21:22
  • @cigien: Hum. That seems to me to be a weak argument. – Bathsheba Oct 13 '20 at 21:23
  • @BenVoigt: Thanks for the edit and for the example! – Bathsheba Oct 13 '20 at 21:24
  • @Bathsheba Hmm, I don't know; c++ is pretty hard to parse for humans, so having fewer things that can go in the same place is probably a good thing. – cigien Oct 13 '20 at 21:25