Why Are Override and Final Identifiers with Special Meaning Instead of Reserved Keywords

Why are C++11 override and final not attributes?

They were, once, before they got changed in response to comment US 44 on C++11's FCD:

Even if attributes continue to be standardized over continued
objections from both of the two vendors who are cited as the principal
prior art, we can live with them with the exception of the virtual
override controls. This result is just awful, as already shown in the
example in 7.6.5 (excerpted):

class D [[base_check]] : public B {
void some_func [[override]] ();
virtual void h [[hiding]] (char*);
};

Here we have six keywords (not counting void and char): three normal
keywords, and three [[decorated]] keywords. There has already been
public ridicule of C++0x about this ugliness. This is just a poor
language design, even in the face of backward compatibility concerns
(e.g., that some existing code may already use those words as
identifiers) because those concerns have already been resolved in
other ways in existing practice (see below). More importantly, this is
exactly the abuse of attributes as disguised keywords that was
objected to and was explicitly promised not to happen in order to get
this proposal passed. The use of attributes for the virtual control
keywords is the most egregious abuse of the attribute syntax, and at
least that use of attributes must be fixed by replacing them with
non-attribute syntax. These virtual override controls are language
features, not annotations.

It is possible to have nice names and no
conflicts with existing code by using contextual keywords, such as
recognizing the word as having the special meaning when it appears in
a grammar position where no user identifier can appear, as
demonstrated in C++/CLI which has five years of actual field
experience with a large number of customers (and exactly no name
conflict or programmer confusion problems reported in the field during
the five years this has been available):

class D : public B {
void some_func() override; // same meaning as [[override]] - explicit override
virtual void h (char*) new; // same meaning as [[hiding]] - a new function, not an override
};
int override = 42; // ok, override is not a reserved keyword

The above forms are implementable, have been implemented, have years
of practical field experience, and work. Developers love them. Whether
the answer is to follow this existing practice or something else,
there needs to be a more natural replacement for the currently
[[attributed]] keywords for virtual override control which is an ugly
novelty that has no field experience and that developers have already
ridiculed.

Why override/final need to placed after function declarator?

It's because override and final are not keywords.

Instead they are special identifiers.

That means you can actually declare variables, functions or type-names (type-alias or classes) with those names.

They can only be used like member-function modifiers in a very small context, where the context have to be know beforehand by the compiler as it parses the source. Placing them after the function declaration is a very simple way of removing ambiguity from the C++ grammar for that context.

Why override is at the end in C++11?

The proposal for the addition of the keywords controlling override (override/final) , paper N3151 , gives us some insight about this choice (emphasis mine) :

It is preferable to put such virtual control keywords at the end of
the declaration so that they don't clash with eg. return types at the
beginning of declarations.

[...]

For context-insensitive, normal keywords, it's less important where
the keywords are placed because the words are reserved. We could put
them at the beginning of declarations or at the end.

During the discussion of attributes, Francis Glassborow pointed out
that the beginning of declarations is becoming crowded. If we put the
virtual control keywords at the beginning, we can end up with examples
like the one below:

struct B
{
virtual volatile const unsigned long int f()
volatile const noexcept;
void f(int g);
};

struct D : B
{
virtual hides_name virtual_override final_overrider volatile const unsigned long int f()
volatile const noexcept;
};

Putting the new keywords at the end at least alleviates the situation
somewhat:

struct B
{
virtual volatile const unsigned long int f()
volatile const noexcept;
void f(int g);
};

struct D : B
{
virtual volatile const unsigned long int f()
hides_name virtual_override final_overrider volatile const noexcept;
};

There are people who think these control keywords should be in the
same place with virtual. As mentioned, that place is already crowded.


Note:

The C++ 11 Standard defines context sensitive keywords in section § 2.11 / 2 [lex.name] :

The identifiers in Table 3 have a special meaning when appearing in a
certain context. When referred to in the grammar, these identifiers
are used explicitly rather than using the identifier grammar
production. Unless otherwise specified, any ambiguity as to whether a
given identifier has a special meaning is resolved to interpret the
token as a regular identifier.

Table3:

final override

What are the new reserved words in C++11?

alignas
alignof
char16_t
char32_t
constexpr
decltype
default
export
noexcept
nullptr
static_assert
thread_local
using

override and final are reserved only in certain contexts.

http://en.cppreference.com/w/cpp/keyword

Why was override made to appear after a member declaration instead of same place as virtual?

The declaration specifier sequence that appears before the function name can contain an identifier (for example, the return type of the function). Imagine some existing code had a return type of override:

override foo();

Or even a variable called override:

int override;

Introducing a new keyword override would break any existing code that contained an identifier named override because keywords are reserved.

So instead of introducing a new keyword, they introduced a contextual keyword: override (and also final). A contextual keyword is identified as a keyword by its syntactic position. It is still fine to have identifiers called override and final in your program. If these identifiers appear after the argument list in a function declaration, they have a special meaning.

So the reason it is placed after the function arguments is because introducing new keywords will break old code and if the compiler sees override here they know exactly what it means, since no other identifier could appear here.



Related Topics



Leave a reply



Submit