Semicolon after Function

后端 未结 6 1489
广开言路
广开言路 2021-02-18 12:57

Is there a specific reason why some people put a semicolon after the curly closing function bracket?

void foo() {

};
6条回答
  •  南方客
    南方客 (楼主)
    2021-02-18 13:29

    Why they do it is probably purely a matter of personal style (and a rather strange one, I'd add). But the legality of this is a completely different matter. In pre-C++14 versions of the language it depends on the scope in which this function definition is made.

    If you define such function in namespace scope, then the trailing ; has nothing to do with the function definition. In C++98 and C++03 it would simply be a syntax error. C++11 introduced (or "legalized") so called empty declarations in namespace scope (but not in class scope). So, that extra semicolon simply constitutes a separate empty declaration, which follows the function definition. This also means that in namespace scope you can add as many extra superfluous semicolons as you wish.

    If you define such function in class scope, then it is a different story. In all versions of the language (starting from C++98) you have always been allowed to add a single optional ; at the end of an in-class function definition. Such ; is an integral part of the function definition and it is explicitly allowed by the grammar. I.e. in class scope that trailing ; does not constitute an independent empty definition. This also means that in class scope you can only add one optional ; after function definition, but not more.

    However, in C++14 in order to resolve some issues caused by that optional ; in class method definitions C++14 re-designed this part of the grammar. Now the grammar for in-class member function definition no longer contains the aforementioned optional ;. Instead, starting from C++14 classes now support empty member declarations as well. So, the meaning of that redundant ; is now consistent across all scopes: it is just an independent empty declaration tacked on at the end of a function definition.

    So, to summarize the above with an example

    struct S
    {
      void foo()
        {};      // <- Legal and has always been legal
      void bar()
        {};;     // <- Legal starting from C++14, error before that
    };
    
    void baz()
    {
    };           // <- Legal starting from C++11, error before that
    

提交回复
热议问题