cplusplus / draft

C++ standards drafts
http://www.open-std.org/jtc1/sc22/wg21/
5.66k stars 748 forks source link

Some rules are omitted in [dcl.ptr], [dcl.ref], [dcl.mptr], [dcl.array], [dcl.fct] #4712

Open xmh0511 opened 3 years ago

xmh0511 commented 3 years ago

the type of the declarator-id in D is “derived-declarator-type-list noexcept opt function of parameter-type-list cv-qualifier-seq optref-qualifieropt returning T”, where...

The type of the declarator-id in D is “derived-declarator-type-list noexceptoptfunction of parameter-type-list cv-qualifier-seq optref-qualifieroptreturning U”, where..

A type of either form is a function type.

How about if "derived-declarator-type-list" is not empty(e.g, "pointer to" )? Is it, in either case, a function type? It obviously not. I think it should be:

A type of either form is a function type if the derived-declarator-type-list is empty.

The following rule is used to state what kind of declaration declares a function, It emphasizes that a typedef declaration with function type does not declare a function, which is a lack in the standard.

a function declaration declares a function.

It should have the similar modification for [dcl.ptr], [dcl.ref], [dcl.mptr], [dcl.array].

[dcl.ptr]

the type of the declarator-id in D is “derived-declarator-type-list cv-qualifier-seq pointer to T”.

The type is a pointer type if the derived-declarator-type-list is empty. An object declaration with the pointer type declares a pointer.

[dcl.ref]

the type of the declarator-id in D is “derived-declarator-type-list reference to T”

The type is a reference type if the derived-declarator-type-list is empty. An object declaration with the reference type declares a reference.

[dcl.mptr]

the type of the declarator-id in D is “derived-declarator-type-list cv-qualifier-seq pointer to member of class nested-name-specifier of type T”

The type is a pointer-to-member type if the derived-declarator-type-list is empty. An object declaration with the pointer-to-member type declares a pointer to member.

[dcl.array]

the type of the declarator-id in D is “derived-declarator-type-list array of N T”.

The type is an array type if the derived-declarator-type-list is empty. An object declaration with the array type declares an array.

The above modification together with the following rule simultaneously clarifies that a typedef declaration with a reference type or an object type does not declare a variable, for which I don't find any strong evidence in the current draft; Since there is no rule in the current draft states what is the declaration of a reference or an object.

If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with a declarator-id is a function type ([dcl.fct]) and an object declaration otherwise.

xmh0511 commented 3 years ago

@jensmaurer Could you please take a look at this issue? I think the current draft totally lacks to define these special types. Simultaneously, these special types are used to form some normative rules somewhere in the standard. For instance

If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with a declarator-id is a function type ([dcl.fct]) and an object declaration otherwise.

As aforementioned in the issue, the function type is not clearly defined. Similar issues are scattered in the standard.

jensmaurer commented 3 years ago

[basic.compound] claims to define these special types, although the italics in p1 is missing "... type" in each case. I would not object to moving the normative definition to [dcl.meaning] where we define the quoted-type-name-string in each case, and use that notation in [basic.compound] to streamline the auxiliary definitions there. For example, we could say

The type "cv-qualifier-seq pointer to T" is termed a function pointer type if T is a function type and an object pointer type if T is void or an object type."

xmh0511 commented 3 years ago

Agreed. Since each clause in [dcl.meaning] has introduced the relevant type for the declarator-id mentioned in the clause, it's reasonable to place the definition of these special types into these clauses, respectively. It's also a concise way to just restrict what "derived-declarator-type-list" that appears in the relevant type should be to introduce these special types. For instance, the adjustment of the parameter type already has a concrete definition in [dcl.fct], we just use it by restricting the "derived-declarator-type-list" to be empty to introduce the function type.

In addition, give a normative definition of which declaration would define a reference or another entity is also significant. For example, the following rule refers such the use

A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable's name, if any, denotes the reference or object.

Since a declaration of a reference hasn't a normative definition, it's what I said in the above comment, we should define it with the help of using the special type, and the object declaration that has been defined in the standard to clarify the concept. Simultaneously, it will also solve the non-explicit defined concept that a typedef-declaration of T does not introduce an entity of type T(function, reference, object...).