Is it guaranteed that all forms of Undefined Behavior are caught when evaluating a constant expression

Viewed 189

I came across the following claim:

Actually, all forms of UB in the language are required to be caught when evaluating a constant expression (though UB in the standard library is not required to be caught). It's only runtime UB where anything can happen.

(emphasis mine)

My question is that is the above statement technically correct?

Upon asking the user how does the standard impose this, they cited expr.const#5.8, which states:

5. 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:

5.8. an operation that would have undefined behavior as specified in [intro] through [cpp];

But after reading the above [expr.const#5.8], I could not figure out how this implies that all forms of UB in the language are required to be caught when evaluating a constant expression. So can someone clarify how does this citation support (if it does) the claim made in the comment quoted above?


I also read this which says:

If the behavior is undefined, the compiler could accept it, reject it, issue a warning, and according to the standard, even crash, hang or install a virus on your computer.

So it seems to me (upon reading the very first comment) that there is a fundamental difference between UB during the evaluation of a constant expression and a runtime UB.

What is the truth?

1 Answers

i could not figure out how this implies that all forms of UB in the language are required to be caught when evaluating a constant expression.

Not necessarily for all forms of UB. As per the quoted rule, only if operation is that is evaluated would have undefined behavior as specified in [intro] through [cpp];.

No other UB such as specified in other sections, or UB that isn't caused by evaluation of an operation, prevents an expression from being core constant. There is a clarifying rule:

[expr.const]

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], or an invocation of the va_­start macro ([cstdarg.syn]), it is unspecified whether E is a core constant expression.

This clarification (including the "as specified in ..." sentence from question) is a resolution to defect report 1952 and the wording is in C++17.


To clarify, the rule causes certain UB to prevent an expression from being core constant. Consider a case where a rule requires an expression to be constant. Here is a an example of such rule:

[dcl.array]

 D1 [ constant-expression opt ] attribute-specifier-seq opt 

... The constant-expression shall be a converted constant expression of type std​::​size_­t ([expr.const]). Its value N specifies the array bound, i.e., the number of elements in the array; ...

If some context requires an expression to be constant, then the expression not being constant will violate that rule. In such case this applies:

[intro.compliance.general]

If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this document as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.

Related