Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The definition of what entity denoted by a qualified-id is not clear #5346

Open
xmh0511 opened this issue Mar 17, 2022 · 20 comments
Open

The definition of what entity denoted by a qualified-id is not clear #5346

xmh0511 opened this issue Mar 17, 2022 · 20 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Mar 17, 2022

[expr.prim.id.qual] p5 states that

The result of a qualified-id Q is the entity it denotes ([basic.lookup.qual]).

The emphasized subclause has no actual interpretation. [basic.pre] p5 define what entity is denoted by a name.

An entity E is denoted by the name (if any) that is introduced by a declaration of E

So, I think [expr.prim.id.qual] p5 should be changed to:

The result of a qualified-id Q is the entity denoted by the qualified name of Q.

@jensmaurer
Copy link
Member

The cross-reference is present not for "denotes", but for the definition of qualified name lookup.

@opensdh, the suggested change seems to better map the grammar qualified-id to the subject of interest for [basic.lookup.qual], which is a qualified name.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 17, 2022

@jensmaurer @opensdh A special case is:

this->~C();  // ~C is an unqualified-id
this->C::~C(); // C::~C is a qualified-id

where the qualified-id C::~C should intend to denote the destructor(member function) of class C. This is not only the issue qualified-id has but unqualified-id also has. [basic.lookup.qual.general] p4 only requires that the qualified name C can be found in the scope of C

Each lookup for Q considers only types (if Q is not followed by a <) and templates whose specializations are types. If it finds nothing or is ambiguous, it is discarded.

Anyway, the result of the lookup could arguably say to be the injected-class-name of C that denotes a type rather than a function(i.e. expected destructor).

@languagelawyer
Copy link
Contributor

I think [expr.prim.id.qual] p5 should be changed to:

The result of a qualified-id Q is the entity denoted by the qualified name of Q.

An entity can be a result only if lookup finds function(s). If it finds a variable or NSDM, the result is the corresponding object, not the entity.

@jensmaurer
Copy link
Member

This touches upon the unsolved variable / object confusion. Note, however, that decltype(X::Y) refers to the entity Y (even if it is a non-static data member or a variable), not to the object.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 18, 2022

If it finds a variable or NSDM, the result is the corresponding object, not the entity.

That is the reason why [basic.pre] p3 admits object and reference are entities but variable is not. If an (unqualified or qualified) name is resolved to be introduced by a declaration of an object, the name just denotes an object.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 18, 2022

@jensmaurer But, @languagelawyer's opinion introduces another issue that, consider a more simple case, which is:

int i = 0;  // a declaration of an object.
i;
new(&i) int{1};
i;
new(&i) int{2};
i;
new(&i) int{3};
i;

[basic.lookup] is only able to resolve the name i to denote a family of int objects since the name is introduced by a declaration of an int object. But we say

The result is the entity denoted by the unqualified-id ([basic.lookup.unqual]).

So, which object does the name i denote when encountering it every time? This issue arises from the conflict between the above definition and the following wording:

A glvalue is an expression whose evaluation determines the identity of an object or function.

The result of a glvalue is the entity denoted by the expression.

An unqualified-id is an expression. So, should we change the above bullet to

An unqualified-id that is the name N denotes the entity introduced by the declaration that introduces N ([basic.lookup.unqual]).

The result of a glvalue is the identified entity(i.e. after evaluation)

@jensmaurer
Copy link
Member

I think we agree that lookup should find the variable "i", and it's conceptually an additional step to determine the object or function to which the glvalue named as "i" refers.

Unfortunately, cleaning this up is a larger undertaking. My guess is we want to restrict "entity" to things that are syntactically declared and thus have a name (variables, data members, structured bindings, function declarations) and use "object or function" for the target of a glvalue. We can probably conflate "function declaration" and "function", because there is a 1:1 mapping.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 18, 2022

it's conceptually an additional step to determine the object or function to which the glvalue named as "i" refers.

It sounds like the step is the duty of the evaluation of the (glvalue) expression, which determines the actual object/function the name "i" denotes at that moment.

Instead, [basic.lookup] is just concerned about the declaration that introduces the name, which restricts what kind of entities the name can denote, and so, the name should have the corresponding properties introduced by the declaration, which will determine what context in which the name is syntactically and semantically correct. In other words, [basic.lookup] cannot determine the result of the expression(id-expression), if we read "result" as what actual object/function/... the name denotes at this moment.

@jensmaurer
Copy link
Member

Mostly agreed. [basic.lookup] actually uniquely determines the entity to which the name refers (except for functions because of overloading).

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 18, 2022

Mostly agreed. [basic.lookup] actually uniquely determines the entity to which the name refers (except for functions because of overloading).

So, that is the motivation why I want to change the definition to that as written in #5346 (comment), which might avoid the hazy regarding "result".

@opensdh
Copy link
Contributor

opensdh commented Mar 19, 2022

I agree that the original suggestion is a (minor) improvement.

I also agree that there isn't really any wording that says that lookup can ever find a destructor: [class.dtor]/1 explains how to interpret a declarator-id that begins with ~, but ~T is not a name ([basic.pre]/4) and (unsurprisingly) can't be the same as anything (/9). The note in [expr.prim.id.unqual]/1 suggests that [expr.prim.id.dtor] covers this (which might be why I missed it for P1787), but in fact the latter relies on "denotes the destructor" rather than defining it. This should perhaps be treated as a separate issue.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 19, 2022

@opensdh How to fix the confusion to the "result" between [basic.lookup] and "expression evaluation". The definition of the result of an unqualified-id or qualified-id that is a glvalue relies on what entity the (unqualified or qualified ) name denotes. However, [basic.lookup] only associates the name with the found declaration, it cannot determine which actual object/ function...(entity) the name denotes at any time.

@opensdh
Copy link
Contributor

opensdh commented Mar 21, 2022

Precisely because lookup as a static operation cannot identify a particular object, I strongly believe that we should stop saying that an object is an "entity". Then [expr.prim.id.general] can describe how the lookup result (e.g., a variable) is used to identify an object/function in much the same way as [expr.ref] describes how a lookup result (e.g., non-static data member) is used to identify a (sub)object or other member.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 21, 2022

That means, we must firstly clarify the following issues:

  • the definition of variable, which are variables.
  • which object/reference is associated with a variable.

@languagelawyer
Copy link
Contributor

which object/reference is associated with a variable.

«which object is associated with a variable» should be enough

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 21, 2022

«which object is associated with a variable» should be enough

Maybe not enough. Since we have [basic.stc.thread]

There is a distinct object or reference per thread, and use of the declared name refers to the entity associated with the current thread.

@languagelawyer
Copy link
Contributor

Maybe not enough. Since we have [basic.stc.thread]

«should be enough» does include changing places which care about references for no reason.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 22, 2022

Maybe not enough. Since we have [basic.stc.thread]

«should be enough» does include changing places which care about references for no reason.

Seems right that we don't need to concern with reference. Except for objects, functions maybe?

@opensdh
Copy link
Contributor

opensdh commented Jun 17, 2022

Now that I think about it more, I see that the resolution to the separate(d) #5449 (along with properly handling the other special case of concept-ids) will in fact invalidate the simple solution proposed here; I'll address both of these in my current paper.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Jun 20, 2022

Now that I think about it more, I see that the resolution to the separate(d) #5449 (along with properly handling the other special case of _concept-id_s) will in fact invalidate the simple solution proposed here; I'll address both of these in my current paper.

Please also look into this issue cplusplus/CWG#44

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants