Open xmh0511 opened 1 year ago
"evaluation" is following the execution flow, not the lexical appearance.
For example, a loop has fresh evaluations for each execution of the loop body.
[intro.abstract] p5 pretty clearly says that it's the actual execution in the abstract machine that can produce undefined behavior.
If you feel "preceding" in [intro.abstract] p5 can be misread as lexical, maybe "preceding ... in that execution" would be clearer?
Because [intro.execution] p7 says:
Evaluation of an expression (or a subexpression) in general includes both value computations (including determining the identity of an object for glvalue evaluation and fetching a value previously assigned to an object for prvalue evaluation) and initiation of side effects.
The evaluation of an expression is statically analyzed and determined. what kind of evaluation the expression is isn't changed with each execution of the evaluation. For example, +a
in this expression, the evaluation is statically determined as value computation, the kind of evaluation is just that and every execution of the expression just reads the object's value. Not strictly speaking, evaluation just describes what the expression will do/perform, or say it is more like a scheme, the execution of the evaluation will actually do what it should act.
Saying that the execution of such evaluation results in UB, which is clearer, I think.
I don't agree with your interpretation of the words; I think that's not what the existing English phrasing says. The fact that we are fetching a value (as opposed to, say, modifying a value) might be a compile-time determination, but that doesn't contradict the idea that the value is actually fetched every time we execute the surrounding statement.
For example,
void f(bool b, int x, int y)
{
(b ? x : y) = 5;
}
will arguably "determine the identity of an object" (whether you want x or y) at runtime.
If anything needs to be done at all in this area, we might want to clarify that any "evaluation" is a runtime (execution) property, not a compile-time one. I'm opposed to adding "executed evaluation" or so everywhere; that's clutter.
Specific suggestions for [intro.abstract] or [expr] welcome.
we might want to clarify that any "evaluation" is a runtime (execution) property, not a compile-time one.
Evaluations might be executed at compile-time. For example:
constexpr int fun(bool b){
if(b){
return 0;
}else{
int i = 0;
i++ + i; // note the evaluation, which would cause UB
return 1;
}
}
int main(){
constexpr int v = fun(true); // this is ok because the evaluation containing unwell-defined behavior won't be executed
}
All implementations compile this example, however, it is a bit unclear in [expr.const] p5
An expression E is a core constant expression unless the evaluation of E, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:
- [...]
- an operation that would have undefined behavior as specified in [intro] through [cpp], excluding [dcl.attr.assume];
It is unspecified whether E is a core constant expression if E satisfies the constraints of a core constant expression, but evaluation of E would evaluate
- an operation that has undefined behavior as specified in [library] through [thread],
In this context, we should view "evaluation" as "the execution of the evaluation". It is even that changing the verb "evaluate" to "execute" is closer to the intent.
I think we should emphasize that the executed evaluation will make the program undefined behavior if the evaluation contains any unwell-defined operations, regardless the execution is at compile or run time. This may be as a common rule specify in [intro.abstract] or [expr]. The key point is the evaluation itself that has undefined behavior may not impact the program or suppress an expression from being a core constant expression but the execution of the evaluation is poison.
I want the word "evaluation" in the standard to mean (what you describe as) "execution of an evaluation", thus actually saying "execution of an evaluation" in the words everywhere is (or will be) redundant. I believe we're quite close to that, but maybe there's some incremental improvement we could apply in some areas. Again, specific wording improvement suggestions that go in this direction are welcome.
You suggestion above goes in the opposite direction.
(You were apparently somehow misled to take a different turn when reading the words, so if we can identity where that happened, we can fix that place.)
Full name of submitter (unless configured in github; will be published with the issue): Jim X
We have specified UB for certain evaluations of expressions, such as:
[expr.pre] p4
[basic.indet] p2
Consider this example
Since the condition is
false
, the statement won't be executed, is this program undefined behavior? [intro.abstract] p5 saysSo, in this example, Is
cc
printing0
guaranteed?Suggested resolution
Is undefined behavior defined for just evaluations or for these executed evaluations? This issue is similar to https://github.com/cplusplus/CWG/issues/268 but this is a more general issue.