Open xmh0511 opened 2 years ago
I take the "similarly for the definition of a static data member of a class." that your case of a static data member is one that doesn't fit the "inhabits the same scope" rule. We could flesh that out a little by saying "An omitted array bound in the definition of a static data member of a class is taken to be the same as the array bound specified in the declaration of the static data member in the /class-specifier/."
To your second point, I'm not reading this from the normative text you quoted. "earlier declaration" applies only if that has a specified bound. In your case, the earlier declaration doesn't have a bound, so the rule doesn't apply.
I think there could still be a problem here:
namespace N {extern int x[1];}
int N::x[];
The "inhabits the same scope" ("in the same scope" in C++20) is meant to deal with the ugly cases of block-scope extern
declarations.
In your case, the earlier declaration doesn't have a bound, so the rule doesn't apply.
[basic.lookup.general] p1 says
Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the semantic properties introduced by the declarations used in further processing.
extern int arr[]; // #1 earlier declaration
int arr[10]; // #2 later declaration
int i = sizeof(arr); // #3
All declarations can be found at #3
, which declaration determines the size
property at #3
? In normal cases, two declarations that declare the same entity should have the same type per [basic.link] p11. However, this is an exception for declaring array. Although, [basic.types.general] p6 says
The declared type of an array object can be an array of unknown bound and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points (“array of unknown bound of T” and “array of N T”) are different types.
Consider a more confused example
extern char buffer[];
char buffer[128];
decltype(buffer) arr;
which declaration's type is used in the declaration of arr
?
The "inhabits the same scope" ("in the same scope" in C++20) is meant to deal with the ugly cases of block-scope extern declarations.
@opensdh So, that's why I want to use "Name is bound in the scope" to try to clarify the rule. [dcl.meaning.general] p3.5 has specified that the name introduced by a block variable declared with extern
is bound in the block scope the declaration inhabits, whereas the innermost enclosing namespace declaration(if any) binds its name in the namespace scope. Altough, it is not clear to me that whether a declaration whose declarator-id is an qualified-id introduces a name or not. [dcl.meaning.general] p3.4 grants that such a declaration's target scope is the same as that of the initial declaration. [basic.scope.scope] p2 says
Unless otherwise specified:
- [...]
- Any names (re)introduced by a declaration are bound to it in its target scope.
The only doubt for the suggestion is whether the qualified-id as a declarator-id introduces a name(qualified name)?
I don't like "bound in a scope" for this purposes. Name binding sometimes does not occur (e.g. for friends), and we're not really talking about name lookup here, but about declaration matching and inheriting properties from earlier declarations.
@jensmaurer About the opinion in this https://github.com/cplusplus/draft/issues/5464#issuecomment-1124427614. What do you think about that? which declaration of the entity determines the properties when the name is used.
I don't like "bound in a scope" for this purposes. Name binding sometimes does not occur (e.g. for friends), and we're not really talking about name lookup here
"name bound in a scope" is a trick that wants to refer to [dcl.meaning.general] p3.5 to check whether the declaration that omits the array bound inhabits a block scope. I think [dcl.meaning] does not talk about names but declarations. Except for this expectation, all other declarations whose declarator-ids are qualified-ids can inherit the array bound from the initial declaration even though they do not inhabit the same scope. Maybe, the direct way is:
Furthermore, if there is a reachable declaration of the entity that supplies the array bound, an omitted array bound of a declaration of the entity is taken to be the same as in that declaration. If the declarator-ids of the two declarations are both unqualified-ids, they shall inhabit the same scope.
Oh, we agree that "inhabit the same scope" is not the right phrasing to use; neither for namespace members nor for class members. I just disagree that "bound in a scope" is necessarily the right tool to fix the phrasing.
I think that the properties of an entity are determined by the union of all declarations that are reachable. "inline" might be in a similar category.
I think that the properties of an entity are determined by the union of all declarations that are reachable. "inline" might be in a similar category.
This point is not very clear in the current draft. We might change the last sentence of [basic.lookup.general] p1 to make that meaning clear.
Only after name lookup, function overload resolution (if applicable) and access checking have succeeded is the union of these semantic properties introduced by the declarations used in further processing.
[dcl.array] p8 says
Consider the example
It's not true. Since the declaration outside the class definition does not inhabit the same scope as the initial declaration does. Since [basic.scope.scope] p2 says
The locus of the second declaration is immediately after the complete declarator, the scope it inhabits is the namespace scope. Moreover, [dcl.meaning.general] p3.1 strongly implies this point
The comment is just wrong. If the comments are the intent. We might say
The earlier declaration implies that the declaration with the specified bound should be declared before another declaration that omits the bound, which rejects this valid example
@jensmaurer @opensdh