Discussion:
Why does the standard need to say that an unevaluated operand is a full-expression?
(too old to reply)
Alexander
2018-05-04 12:53:24 UTC
Permalink
In other words, what would be the difference if we didn't have paragraph
(5.1) below and the last sentence in [expr.context]/1 were eliminated?

[intro.execution]/5 <http://eel.is/c++draft/intro.execution#5>:

5 A full-expression is
(5.1) — an unevaluated operand (8.2),
(5.2) — a constant-expression (8.6),
(5.3) — an init-declarator (Clause 11) or a mem-initializer (15.6.2),
including the constituent expressions of the initializer,
(5.4) — an invocation of a destructor generated at the end of the lifetime
of an object other than a temporary object (15.2), or
(5.5) — an expression that is not a subexpression of another expression and
that is not otherwise part of a full-expression.

[expr.context]/1 <http://eel.is/c++draft/expr.context#1>:

In some contexts, unevaluated operands appear (8.4.7, 8.5.1.8, 8.5.2.3,
8.5.2.7, 10.1.7.2, Clause 17). An
unevaluated operand is not evaluated. [ Note: In an unevaluated operand, a
non-static class member may be
named (8.4) and naming of objects or functions does not, by itself, require
that a definition be provided (6.2).
*An unevaluated operand is considered a full-expression* (6.8.1). —end note
]

Of course the question applies to a constant-expression as well, that is,
why does the Standard need to say that a constant expression is a
full-expression, as long as the constant-expression is not a subexpression
of another expression?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Smith
2018-05-04 19:20:15 UTC
Permalink
Post by Alexander
In other words, what would be the difference if we didn't have paragraph
(5.1) below and the last sentence in [expr.context]/1 were eliminated?
5 A full-expression is
(5.1) — an unevaluated operand (8.2),
(5.2) — a constant-expression (8.6),
(5.3) — an init-declarator (Clause 11) or a mem-initializer (15.6.2),
including the constituent expressions of the initializer,
(5.4) — an invocation of a destructor generated at the end of the lifetime
of an object other than a temporary object (15.2), or
(5.5) — an expression that is not a subexpression of another expression
and that is not otherwise part of a full-expression.
In some contexts, unevaluated operands appear (8.4.7, 8.5.1.8, 8.5.2.3,
8.5.2.7, 10.1.7.2, Clause 17). An
unevaluated operand is not evaluated. [ Note: In an unevaluated operand, a
non-static class member may be
named (8.4) and naming of objects or functions does not, by itself,
require that a definition be provided (6.2).
*An unevaluated operand is considered a full-expression* (6.8.1). —end
note ]
Of course the question applies to a constant-expression as well, that is,
why does the Standard need to say that a constant expression is a
full-expression, as long as the constant-expression is not a subexpression
of another expression?
Given:

bool b = noexcept(X() + Y());

... the destructors of X() and Y() are part of the operand of noexcept, and
are not run at the end of the initializer of b. However, for better or
worse, the calls to X() and Y() are (currently) described as being
subexpressions of the initializer of b.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Alexander
2018-05-05 07:46:51 UTC
Permalink
Post by Richard Smith
bool b = noexcept(X() + Y());
... the destructors of X() and Y() are part of the operand of noexcept,
and are not run at the end of the initializer of b. However, for better or
worse, the calls to X() and Y() are (currently) described as being
subexpressions of the initializer of b.
The compiler knows that the operand of a noexcept operator are unevaluated (
[expr.unary.noexcept]/1 <http://eel.is/c++draft/expr.unary.noexcept#1>). It
doesn't need to worry about constructors and destructors being invoked in
this case.The compiler doesn't need to be told that the expression
noexcept(X() + Y()) is a full-expression, simply because this expression is
not a subexpression of another expression.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Alexander
2018-05-05 13:29:34 UTC
Permalink
Post by Alexander
The compiler knows that the operand of a noexcept operator are unevaluated
([expr.unary.noexcept]/1 <http://eel.is/c++draft/expr.unary.noexcept#1>).
It doesn't need to worry about constructors and destructors being invoked
in this case.The compiler doesn't need to be told that the expression
noexcept(X() + Y()) is a full-expression, simply because this expression is
not a subexpression of another expression.
Please consider the correction below:

The compiler knows that the operand of a noexcept operator
<strike>are</strike> is unevaluated ([expr.unary.noexcept]/1
<http://eel.is/c++draft/expr.unary.noexcept#1>). It doesn't need to worry
about constructors and destructors being invoked in this case.The compiler
doesn't need to be told that the expression noexcept(X() + Y()) is a
full-expression, simply because this expression is not a subexpression of
another expression.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Smith
2018-05-05 22:50:16 UTC
Permalink
Post by Alexander
Post by Alexander
The compiler knows that the operand of a noexcept operator are
unevaluated ([expr.unary.noexcept]/1
<http://eel.is/c++draft/expr.unary.noexcept#1>). It doesn't need to
worry about constructors and destructors being invoked in this case.The
compiler doesn't need to be told that the expression noexcept(X() + Y()) is
a full-expression, simply because this expression is not a subexpression of
another expression.
The compiler knows that the operand of a noexcept operator
<strike>are</strike> is unevaluated ([expr.unary.noexcept]/1
<http://eel.is/c++draft/expr.unary.noexcept#1>). It doesn't need to worry
about constructors and destructors being invoked in this case.
This is a bit subtle, but it actually does. Consider:

struct A { void f(); ~A() noexcept(false); };
bool b = noexcept(A());

The compiler needs to know that the destructor of the A object runs
*within* the noexcept expression, so that it can give the correct result
here: b == false, because the destructor of A can throw. For that to
happen, we need the full-expression of A() to be just the A() expression,
not the entire initializer of b.
Post by Alexander
The compiler doesn't need to be told that the expression noexcept(X() +
Y()) is a full-expression, simply because this expression is not a
subexpression of another expression.
The additional full-expression here is X() + Y(), not noexcept(X() + Y()).
But X() + Y() *is* a subexpression of noexcept(X() + Y()), because X() +
Y() is an operand of the noexcept operator.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Alexander
2018-05-06 13:47:56 UTC
Permalink
Post by Richard Smith
struct A { void f(); ~A() noexcept(false); };
bool b = noexcept(A());
The compiler needs to know that the destructor of the A object runs
*within* the noexcept expression, so that it can give the correct result
here: b == false, because the destructor of A can throw. For that to
happen, we need the full-expression of A() to be just the A() expression,
not the entire initializer of b.
This is really subtle. Thank you! I suppose the example you gave above
would also answer the constant-expression case, if we define the default
constructor for A, as constexpr. Is this correct?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Alexander
2018-05-06 18:29:04 UTC
Permalink
Post by Alexander
This is really subtle. Thank you! I suppose the example you gave above
would also answer the constant-expression case, if we define the default
constructor for A, as constexpr. Is this correct?
I take back what I said above, for this would fall into [intro.execution]/5
(5.1) <http://eel.is/c++draft/intro.execution#5.1>. Thus, it remains to be
seen an example showing that (5.2)
<http://eel.is/c++draft/intro.execution#5.2> is also necessary, i.e. that
the standard needs to explicitly say that a constant-expression is a
full-expression, if it is not a subexpression of another expression.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Continue reading on narkive:
Loading...