-
Notifications
You must be signed in to change notification settings - Fork 772
[expr] Clarify performing / applying standard conversions. #3955
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -235,9 +235,9 @@ | |
|
||
\pnum | ||
Whenever a glvalue appears as an operand of an operator that | ||
expects a prvalue for that operand, the | ||
expects a prvalue for that operand, an | ||
lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, | ||
or function-to-pointer\iref{conv.func} standard conversions are | ||
or function-to-pointer\iref{conv.func} standard conversion is | ||
applied to convert the expression to a prvalue. | ||
\begin{note} | ||
An attempt to bind an rvalue reference to an lvalue is not such a context; see~\ref{dcl.init.ref}. | ||
|
@@ -433,7 +433,7 @@ | |
expression is called a \defn{discarded-value expression}. | ||
The array-to-pointer\iref{conv.array} | ||
and function-to-pointer\iref{conv.func} standard conversions are not | ||
applied. The lvalue-to-rvalue conversion\iref{conv.lval} is applied | ||
applied. The lvalue-to-rvalue conversion\iref{conv.lval} is performed | ||
jensmaurer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if and only if | ||
the expression is a glvalue of volatile-qualified type and it is one of the | ||
following: | ||
|
@@ -532,6 +532,15 @@ | |
declaration \tcode{T t=$E$;} is well-formed, for some invented temporary | ||
variable \tcode{t}\iref{dcl.init}. | ||
|
||
\pnum | ||
Certain language constructs require that a conversion be performed | ||
on an operand. In such cases, if the conversion is applicable to that operand, | ||
it is applied, otherwise performing the conversion has no effect. | ||
\begin{example} | ||
Performing the lvalue-to-rvalue conversion on an array lvalue has no effect, | ||
because the lvalue-to-rvalue conversion cannot be applied to arrays. | ||
\end{example} | ||
|
||
\pnum | ||
Certain language constructs require that an expression be converted to a Boolean | ||
value. An expression $E$ appearing in such a context is said to be | ||
|
@@ -665,8 +674,10 @@ | |
An lvalue or rvalue of type ``array of \tcode{N} \tcode{T}'' or ``array | ||
of unknown bound of \tcode{T}'' can be converted to a prvalue of type | ||
``pointer to \tcode{T}''. | ||
The temporary materialization conversion\iref{conv.rval} is applied. | ||
The result is a pointer to the first element of the array. | ||
The temporary materialization conversion\iref{conv.rval} is first applied | ||
if the expression is a prvalue. | ||
The result is a pointer to the first element of | ||
the possibly-converted array glvalue. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. glvalue is an expression, it doesn't have elements. |
||
|
||
\rSec2[conv.func]{Function-to-pointer conversion} | ||
|
||
|
@@ -1084,7 +1095,7 @@ | |
|
||
\begin{itemize} | ||
\item If either operand is of scoped enumeration type\iref{dcl.enum}, no conversions | ||
are performed; if the other operand does not have the same type, the expression is | ||
are applied; if the other operand does not have the same type, the expression is | ||
ill-formed. | ||
|
||
\item If either operand is of type \tcode{long double}, the | ||
|
@@ -3111,10 +3122,7 @@ | |
thus each such argument has a corresponding parameter when a function template | ||
specialization is actually called. | ||
\end{note} | ||
The | ||
lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, | ||
and function-to-pointer\iref{conv.func} standard conversions are | ||
performed on the argument expression. | ||
In this case, argument expression is expected to be a prvalue\iref{basic.lval}. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing "the"? |
||
An argument that has type \cv{}~\tcode{std::nullptr_t} is converted | ||
to type \tcode{void*}\iref{conv.ptr}. | ||
After these conversions, if the | ||
|
@@ -3442,7 +3450,7 @@ | |
\pnum | ||
If \tcode{T} is ``pointer to \cv{} \tcode{void}'', then the result | ||
is a pointer to the most derived object pointed to by \tcode{v}. | ||
Otherwise, a runtime check is applied to see if the object pointed or | ||
Otherwise, a runtime check is performed to see if the object pointed or | ||
referred to by \tcode{v} can be converted to the type pointed or | ||
referred to by \tcode{T}. | ||
|
||
|
@@ -3684,11 +3692,6 @@ | |
this direct-initialization defines the type of the expression as \tcode{U[1]}. | ||
\end{note} | ||
|
||
\pnum | ||
Otherwise, the \tcode{static_cast} shall perform one of the conversions | ||
listed below. No other conversion shall be performed explicitly using a | ||
\tcode{static_cast}. | ||
|
||
\pnum | ||
Any expression can be explicitly converted to type \cv{}~\tcode{void}, | ||
in which case it becomes a discarded-value | ||
|
@@ -3701,8 +3704,13 @@ | |
preserved for the purpose of executing the destructor. | ||
\end{note} | ||
|
||
\pnum | ||
Otherwise, the operand is expected to be a prvalue\iref{basic.lval}, and | ||
the \tcode{static_cast} shall perform one of the conversions listed below. | ||
|
||
\pnum | ||
% FIXME: Does this permit any cases that aren't explicitly described below? | ||
% Can this be converted to a note? | ||
The inverse of any standard conversion sequence\iref{conv} not containing an | ||
lvalue-to-rvalue\iref{conv.lval}, | ||
array-to-pointer\iref{conv.array}, | ||
|
@@ -3725,10 +3733,7 @@ | |
\end{example} | ||
|
||
\pnum | ||
The lvalue-to-rvalue\iref{conv.lval}, | ||
array-to-pointer\iref{conv.array}, and | ||
function-to-pointer\iref{conv.func} conversions are applied to the | ||
operand. Such a \tcode{static_cast} is subject to the restriction that | ||
Such a \tcode{static_cast} is subject to the restriction that | ||
the explicit conversion does not cast away | ||
constness\iref{expr.const.cast}, and the following additional rules | ||
for specific cases: | ||
|
@@ -3845,10 +3850,9 @@ | |
\indextext{cast!lvalue}% | ||
If \tcode{T} is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; | ||
if \tcode{T} is an rvalue reference to object type, the result is an xvalue; | ||
otherwise, the result is a prvalue and the | ||
lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, | ||
and function-to-pointer\iref{conv.func} standard conversions are | ||
performed on the expression \tcode{v}. Conversions that can be performed explicitly | ||
otherwise, the result is a prvalue and | ||
the operand \tcode{v} is expected to be a prvalue\iref{basic.lval}. | ||
Conversions that can be performed explicitly | ||
using \tcode{reinterpret_cast} are listed below. No other conversion can | ||
be performed explicitly using \tcode{reinterpret_cast}. | ||
|
||
|
@@ -4007,10 +4011,9 @@ | |
\tcode{T}. If \tcode{T} is an lvalue reference to object type, the result is an | ||
lvalue; | ||
if \tcode{T} is an rvalue reference to object type, the result is an xvalue; | ||
otherwise, the result is a prvalue and the | ||
lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, | ||
and function-to-pointer\iref{conv.func} standard conversions are | ||
performed on the expression \tcode{v}. Conversions that can be performed explicitly using | ||
otherwise, the result is a prvalue and | ||
the operand \tcode{v} is expected to be a prvalue\iref{basic.lval}. | ||
Conversions that can be performed explicitly using | ||
\tcode{const_cast} are listed below. No other conversion shall be | ||
performed explicitly using \tcode{const_cast}. | ||
|
||
|
@@ -5896,7 +5899,8 @@ | |
If both operands have arithmetic types, | ||
or one operand has integral type and | ||
the other operand has unscoped enumeration type, | ||
the usual arithmetic conversions\iref{expr.arith.conv} are applied to the operands. | ||
the usual arithmetic conversions\iref{expr.arith.conv} are | ||
performed on the operands. | ||
Then: | ||
|
||
\begin{itemize} | ||
|
@@ -6011,17 +6015,13 @@ | |
relational-expression \terminal{>=} compare-expression | ||
\end{bnf} | ||
% | ||
The | ||
lvalue-to-rvalue\iref{conv.lval}, | ||
array-to-pointer\iref{conv.array}, | ||
and function-to-pointer\iref{conv.func} | ||
standard conversions are performed on the operands. | ||
The operands are expected to be prvalues\iref{basic.lval}. | ||
The comparison is deprecated if | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ending the previous sentence with a semicolon and continuing with "the comparison is deprecated if [...]" flows better. |
||
both operands were of array type | ||
prior to these conversions\iref{depr.array.comp}. | ||
an array-to-pointer\iref{conv.array} conversion | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The array-to-pointer conversion is a single conversion -- I think "an" should be "the" here. |
||
is applied to both operands\iref{depr.array.comp}. | ||
|
||
\pnum | ||
The converted operands shall have arithmetic, enumeration, or pointer type. | ||
The operands shall have arithmetic, enumeration, or pointer type. | ||
The | ||
operators \tcode{<} (less than), \tcode{>} (greater than), \tcode{<=} | ||
(less than or equal to), and \tcode{>=} (greater than or equal to) all | ||
|
@@ -6092,17 +6092,13 @@ | |
\pnum | ||
The \tcode{==} (equal to) and the \tcode{!=} (not equal to) operators | ||
group left-to-right. | ||
The | ||
lvalue-to-rvalue\iref{conv.lval}, | ||
array-to-pointer\iref{conv.array}, | ||
and function-to-pointer\iref{conv.func} | ||
standard conversions are performed on the operands. | ||
The operands are expected to be prvalues\iref{basic.lval}. | ||
The comparison is deprecated if | ||
both operands were of array type | ||
prior to these conversions\iref{depr.array.comp}. | ||
an array-to-pointer\iref{conv.array} conversion | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The array-to-pointer conversion is a single conversion -- I think "an" should be "the" here. |
||
is applied to both operands\iref{depr.array.comp}. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "operand" here means the original operand, but... |
||
|
||
\pnum | ||
The converted operands shall have arithmetic, enumeration, pointer, | ||
The operands shall have arithmetic, enumeration, pointer, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "operand" here means the converted prvalue operand. That's non-obvious. |
||
or pointer-to-member type, or type \tcode{std::nullptr_t}. The operators | ||
\tcode{==} and \tcode{!=} both yield \tcode{true} or \tcode{false}, i.e., a | ||
result of type \tcode{bool}. In each case below, the operands shall have the | ||
|
@@ -6456,7 +6452,7 @@ | |
If no conversion sequence can be formed, the operands are left unchanged | ||
and further checking is performed as described below. | ||
Otherwise, if exactly one conversion sequence can be formed, | ||
that conversion is applied to the chosen operand | ||
that conversion sequence is applied to the chosen operand | ||
and the converted operand is used in place of the original operand for | ||
the remainder of this subclause. | ||
\begin{note} | ||
|
@@ -6481,10 +6477,9 @@ | |
subclause. | ||
|
||
\pnum | ||
Lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, | ||
and function-to-pointer\iref{conv.func} standard conversions are | ||
performed on the second and third operands. After those conversions, one | ||
of the following shall hold: | ||
The resulting second and third operands are expected to be | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps we say "possibly-converted" instead of "resulting" |
||
prvalues\iref{basic.lval}. | ||
One of the following shall hold: | ||
|
||
\begin{itemize} | ||
\item The second and third operands have the same type; the result is of | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading all the "expected to be" phrasings below makes me want to ask for "requires" here.
Example: "that requires a prvalue for that operand..." or "The operand is required to be a prvalue."
The "required" conveys better that, if you can't make it so, you're toast. (Just a slight wording preference, not a strong feeling.)