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

[dcl.init.ref] References are bound to objects and functions, not expressions #2856

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

sdkrystian
Copy link
Contributor

Proposed fix to close #2855

@sdkrystian sdkrystian changed the title [dcl.init.ref] References are bound to entities, not expressions [dcl.init.ref] References are bound to objects and functions, not expressions Apr 30, 2019
Copy link
Member

@zygoloid zygoloid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More problems in this area: we sometimes say that references are bound to objects, and sometimes say that [temporary] objects are bound to references; in a couple of places we even say that temporary expressions are bound to references.

then the reference is bound to the initializer expression lvalue in the
first case and to the lvalue result of the conversion
then the reference is bound to the object or function to which the initializer expression refers in the
first case and to the object to which the lvalue result of the conversion refers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "lvalue result of the conversion" here was already correct; see the definition of "result" in [basic.lval]p5. I think we could use "result of" more broadly in this change. Eg:

"the reference is bound to the lvalue result of the initializer expression in the first case and to the lvalue result of the conversion in the second case".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. One gripe I have with it is that when we say "glvalue" result, it could be interpreted in one of two ways, the resulting glvalue of the conversion (see my other comment as to why conversions result in expressions), or the result of the glvalue. It would be best to make it as clear as possible to avoid any confusion.

the reference is bound to the resulting glvalue
(or to an appropriate base class subobject).
the reference is bound to the object or function to which the resulting glvalue
refers (or to an appropriate base class subobject).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just:

is bound to the resulting glvalue -> is bound to the glvalue result

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good

@@ -5429,7 +5432,7 @@
the initializer expression is implicitly converted to a prvalue
of type ``\cvqual{cv1} \tcode{T1}''.
The temporary materialization conversion is applied and the reference is
bound to the result.
bound to the object to which the resulting xvalue refers.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was already correct. The result of a conversion is the entity to which the evaluation of the conversion refers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zygoloid The result of a conversion is defined in terms of value categories, meaning that it's an expression as stated in [conv] p6.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we talk about expressions, we often mean "expression or conversion". That is the case when we define "result" as well as when we defined value categories. I continue to think that this wording is correct as-is, though wording elsewhere may need updating.

@@ -5255,6 +5255,9 @@
\end{codeblock}
\end{example}

\pnum
A reference is said to be \defn{bound} to an object or function \tcode{E} when it is initialized to refer to \tcode{E}.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're splitting the specification for references between here and [dcl.ref]p4. Over there, we find:

"A reference shall be initialized to refer to a valid object or function. [Note: In particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by indirection through a null pointer, which causes undefined behavior. As described in 11.3.9, a reference cannot be bound directly to a bit-field. — end note]"

I think neither place is the right place for these rules to live, though; [basic.compound] seems like a much better home for the above part of [dcl.ref]p4, for this new text, and for the next paragraph ("cannot be changed to refer to another object").

Perhaps add a new paragraph in [basic.compound] such as:

"""
A reference is bound to an entity determined by its initialization ([dcl.init.ref]). [Note: Argument passing ([expr.call]) and function value return ([stmt.return]) are initializations. — end note] If the entity to which a reference is bound is not a valid object or function, behavior is undefined. [Note: In particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by indirection through a null pointer, which causes undefined behavior. As described in 11.3.9, a reference cannot be bound directly to a bit-field. — end note] A reference cannot be changed to bind to another entity after initialization. [Note: Assignment to a reference assigns to the object referred to by the reference ([expr.ass]). — end note]
"""

... and remove the relevant wording from [dcl.init.ref] and [dcl.ref].

Hmm. We also don't appear to anywhere say that naming a reference results in the entity to which it is bound. Maybe the simplest way to deal with that would be to add a rule, perhaps just after [basic.lval]p5:

"If the result of a glvalue expression is a reference, the result is adjusted to be the entity to which the reference is bound."

Copy link
Contributor Author

@sdkrystian sdkrystian May 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zygoloid
Naming a reference will result in the referred to object or function, see [expr.type] p1.

As for the wording you propose to add in [basic.compound], I believe entity is way too broad of a term to use. References only bind to objects and functions, and an entity is a whole laundry list of things, including types and templates. This could potentially be confusing to the reader.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zygoloid

A reference cannot be changed to bind to another entity after initialization.

When I read this, I always have very mixed feelings. On the one hand it is "obvious" that this wording means assignment. On the other hand, this wording is so vague that one might think about indirect change of which object a reference refers to. I mean rules in [basic.life] which list situations when a reference will refer to a new object when suchan object is created.

@18

I believe entity is way too broad of a term to use

There is also an opinion that object should not be entity (@opensdh)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zygoloid

A reference shall be initialized to refer to a valid object or function.

This wording is the concern of CWG453. Is it OK to rewrite it?

@RealLitb
Copy link

Does this need to modify http://eel.is/c++draft/over.ics.ref#1.sentence-1 aswell?

@sdkrystian
Copy link
Contributor Author

@RealLitb No, "bind directly" is defined in terms of expressions http://eel.is/c++draft/dcl.init.ref#5.sentence-2

@jensmaurer jensmaurer added the changes requested Changes to the wording or approach have been requested and not yet applied. label Oct 11, 2019
@wg21bot wg21bot added the needs rebase The pull request needs a git rebase to resolve merge conflicts. label Jun 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changes requested Changes to the wording or approach have been requested and not yet applied. needs rebase The pull request needs a git rebase to resolve merge conflicts.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[dcl.init.ref] References are bound to objects and functions, not expressions
6 participants