2

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?
}
Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
  • 1
    "_it's not obvious to me that every statement in an immediate function is defined as being a constant expression_": This is never required for any statement in a `consteval` function (at least not by virtue of the `consteval` on the function), but also irrelevant as the answer explains. – user17732522 Aug 25 '23 at 17:08

1 Answers1

6

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.

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
Barry
  • 286,269
  • 29
  • 621
  • 977
  • is this "ill-formed - no diagnostic required" ? – ABaumstumpf Aug 25 '23 at 19:36
  • 1
    @ABaumstumpf No. Like I said, it's a "mandatory diagnostic" – Barry Aug 25 '23 at 21:00
  • 1
    @Barry It would have been IFNDR before your [P2448R2](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2448r2.html), wouldn't it? – user17732522 Aug 26 '23 at 10:17
  • 1
    @user17732522 I feel like calling these things IFNDR isn't really meaningful. It's not like an odr-violation, where there is a wide range of behavior you can experience at runtime if you violate that rule. This is just ill-formed code, that the compiler _will definitely diagnose_ if you try to use it, that the compiler used to _also_ be allowed to diagnose even if you don't use it. – Barry Aug 26 '23 at 12:44