Title
Differences in relational and three-way constant comparisons
Status
cd5
Section
7.7 [expr.const]
Submitter
Richard Smith

Created on 2017-11-11.00:00:00 last changed 40 months ago

Messages

Date: 2018-11-15.00:00:00

Proposed resolution (November, 2018):

Change 7.7 [expr.const] bullets 2.22 and 2.23 as follows, merging tbe bullets:

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (6.9.1 [intro.execution]), would evaluate one of the following expressions:

  • ...

  • a three-way comparison (7.6.8 [expr.spaceship]), comparing pointers that do not point to the same complete object or to any subobject thereof;

  • a relational (7.6.9 [expr.rel]), or equality (7.6.10 [expr.eq]) operator where the result is unspecified;

  • ...

Date: 2018-10-15.00:00:00

Notes from the October, 2018 teleconference:

The consensus of CWG was to make the 3-way operator cases non-constant, as the relational cases are.

Date: 2019-02-15.00:00:00

[Accepted as a DR at the February, 2019 meeting.]

According to 7.7 [expr.const] bullets 2.21 and 2.22, the characteristics of three-way and relational comparisons that disqualify them as constant expressions are different:

  • a three-way comparison (7.6.8 [expr.spaceship]) comparing pointers that do not point to the same complete object or to any subobject thereof;

  • a relational (7.6.9 [expr.rel]) or equality (7.6.10 [expr.eq]) operator where the result is unspecified;

These are not equivalent, with odd results:

  struct A {
    int a;
  private:
    int b;
    constexpr auto f() { return &a < &b; }   // not constant 
    constexpr auto g() { return &a <=> &b; } // returns unspecified value 
  };

Similarly,

  struct B { int n; };
  struct C : B { int m; } c;
  constexpr auto x = &c.n < &c.m;   // not constant 
  constexpr auto y = &c.n <=> &c.m; // returns unspecified value 

The three-way rule seems to be the correct one, but additional wording is needed in 7.6.9 [expr.rel] to specify the relational ordering within a single object: addresses of subobjects of the same complete object should be weakly ordered, and when restricted to subobjects that are not permitted to have the same address, should be totally ordered.

History
Date User Action Args
2020-12-15 00:00:00adminsetmessages: + msg6388
2020-12-15 00:00:00adminsetmessages: + msg6387
2017-11-11 00:00:00admincreate