Why are override and final identifiers with special meaning instead of reserved keywords?

坚强是说给别人听的谎言 提交于 2019-11-27 21:52:42
Shafik Yaghmour

Adding new keywords is difficult because it takes away identifiers from the user. It ends up being a trade-off between choosing identifiers that potentially break old code currently using the identifier or choosing names that are highly unlikely to break old code but are ugly or not meaningful to the way they are being used.

In this specific case override and final end up being used in the grammar in places where no user identifiers can appear. So in those places the identifiers can have a special meaning and outside of those contexts they can be treated as a regular identifier leaving the identifiers available for users. C++/CLI has used this technique since 2005 and they are called context-sensitive keywords which is covered in the C++/CLI standard section 9.1.1 Identifiers.

We can see in the write-up that addresses the trade-offs of the different methods of adding support for virtual control attributes in N3163: Override Control Using Contextual Keywords. It discussed three options:

  • Using [[attributes]], which was deemed undesirable for reasons including they are just keywords in disguise (modified example from paper below):

    class A : public B {
      virtual void f [[override]] () { ... }
      virtual void h [[final]] () { ... }
    };
    
  • Use reserved keywords, which potentially breaks existing code unless ugly names are chosen (modified example from paper below):

    class A : public B {
      virtual void f override_func () { ... }
      virtual void h final_func () { ... }
    };
    
  • Use context-sensitive keywords, which does not break existing code allows for nice names (modified example from paper below):

    class A : public B {
      virtual void f() override { ... }
      virtual void h() final { ... }
    };
    

The following paragraph from the paper sums up the argument for using context sensitive keywords over the other two choices (emphasis mine):

The observation was made in Rapperswil that this approach can make error recovery and syntax highlighting more difficult. For example, syntax highlighting is a bit harder because instead of globally highlighting the keyword you need to do parsing to know whether the identifier is in the location where it has special meaning and should be highlighted. But this is not exceptionally difficult, particularly not in comparison to other far more difficult things we already have to do in C++ compared to other languages .

These are minor inconveniences for a few compiler writers for a week, but are seamless for users. This is the right tradeoff. Otherwise, having ugly globally reserved names (Option 2) or inappropriate and visibly bolted - on attributes (Option 1) make things easier for a few compiler writers for a week, but are things millions of users will have to live with forever.

The changes were applied to the standard via N3206: Override control: Eliminating Attributes and N3272: Follow-up on override control.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!