Search code examples
c++language-lawyerc++20

Can undefined behavior that is explicitly specified occur in a consteval function without a diagnostic


Spun off of comments here

3 [intro.defs], 3.65 [defns.undef] says

Evaluation of a constant expression ([expr.const]) never exhibits behavior explicitly specified as undefined in [intro] through [cpp]

Though, reading through [expr.const] it's not obvious to me that every statement in an immediate function is defined as being a constant expression.

If code in a consteval function attempts behavior explicitly described as UB, can the compiler exhibit UB?

consteval void f() {
  int x;
  int y;
  &x - &y;  // UB allowed? or diagnostic required?
}

Solution

  • If code in a consteval function attempts behavior explicitly described as UB, can the compiler exhibit UB?

    No.

    We have two rules here:

    • A (top-level) call to a consteval function must be a constant expression (this rule has become more complicated to spell over the years, my fault, sorry).
    • No undefined behavior is allowed during constant evaluation (this one is explicitly ruled out - you're not allowed to evaluate "an operation that would have undefined behavior as specified in [intro] through [cpp], excluding [dcl.attr.assume]" ([expr.const]/5.8). This is one of a long list of things you're not allowed to do.

    So when you call f(), that has to be a constant expression, which requires following all the rules in [expr.const]/5. Which the &x - &y in there violates. That f() fails to be a core constant expression is a mandatory diagnostic, because it's a consteval function. The program is ill-formed.