Declarations in C++

前端 未结 2 395
星月不相逢
星月不相逢 2021-01-31 07:34

From what I have understood, declarations/initializations in C++ are statements with \'base type\' followed by a comma separated list of declarators.

Consider the follow

2条回答
  •  囚心锁ツ
    2021-01-31 08:16

    This is specified in [dcl.dcl] and [dcl.decl] as part of the simple-declaration* and boils down to differences between the branches in ptr-declarator:

    declaration-seq:
        declaration
    
    declaration:
        block-declaration
    
    block-declaration:
        simple-declaration
    
    simple-declaration:
        decl-specifier-seqopt init-declarator-listopt ;
    ----
    
    decl-specifier-seq:
        decl-specifier decl-specifier-seq    
    
    decl-specifier:    
        type-specifier                               ← mentioned in your error
    
    type-specifier:
        trailing-type-specifier
    
    trailing-type-specifier:
        simple-type-specifier
        cv-qualifier
    ----
    
    init-declarator-list:
       init-declarator
       init-declarator-list , init-declarator
    
    init-declarator:
       declarator initializeropt
    
    declarator:
        ptr-declarator
    
    ptr-declarator:                                 ← here is the "switch"
        noptr-declarator
        ptr-operator ptr-declarator
    
    ptr-operator:                                   ← allows const
        *  cv-qualifier-seq opt
    
    cv-qualifier:
        const
        volatile
    
    noptr-declarator:                               ← does not allow const
        declarator-id
    
    declarator-id:
        id-expression
    

    The important fork in the rules is in ptr-declarator:

    ptr-declarator:
        noptr-declarator
        ptr-operator ptr-declarator
    

    Essentially, noptr-declarator in your context is an id-expression only. It may not contain any cv-qualifier, but qualified or unqualified ids. However, a ptr-operator may contain a cv-qualifier.

    This indicates that your first statement is perfectly valid, since your second init-declarator

     *const p = &i;
    

    is a ptr-declarator of form ptr-operator ptr-declarator with ptr-operator being * const in this case and ptr-declarator being a unqualified identifier.

    Your second statement isn't legal because it is not a valid ptr-operator:

     const c = 2
    

    A ptr-operator must start with *, &, && or a nested name specifier followed by *. Since const c does not start with either of those tokens, we consider const c as noptr-declarator, which does not allow const here.

    Also, why the behaviour differs among 3rd and 4th statements?

    Because int is the type-specifier, and the * is part of the init-declarator,

    *const p1
    

    declares a constant pointer.

    However, in int const, we have a decl-specifier-seq of two decl-specifier, int (a simple-type-specifier) and const (a cv-qualifier), see trailing-type-specifier. Therefore both form one declaration specifier.


    * Note: I've omitted all alternatives which cannot be applied here and simplified some rules. Refer to section 7 "Declarations" and section 8 "Declarators" of C++11 (n3337) for more information.

提交回复
热议问题