This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-01-21


2765. Address comparisons between potentially non-unique objects during constant evaluation

Section: 6.7.2  [intro.object]     Status: open     Submitter: CWG     Date: 2023-07-14

The (arguably) expanded treatment of backing arrays and string literals as potentially non-unique objects in issue 2753 lead to the question how the resulting address comparisons are treated during constant evaluation.

Subclause 7.7 [expr.const] bullet 5.24 specifies:

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:

This phrasing is understood to refer to explicitly unspecified outcomes only. The treatment of an example such as

  constexpr bool b = "abc" == "abc";

is unclear, given that identical string literals may or may not yield distinct string literal objects.

The assumption that equality comparison of std::string_view would compare addresses as a short-cut before comparing the character sequence could not be confirmed (27.2.2 [char.traits.require], 27.3.3.8 [string.view.ops] paragraph 12).

CWG in Tokyo 2024-03-22

Different approaches are feasible:

In the latter cases, tag values can be preserved when performing pointer arithmetic.

Possible resolution (January, 2025)

  1. Add a new paragraph before 6.8.4 [basic.compound] paragraph 4:

    A pointer value pointing to a potentially non-unique object O (6.7.2 [intro.object]) is associated with the evaluation of the string-literal (5.13.5 [lex.string]) or initializer list (9.4.5 [dcl.init.list]) that resulted in the string literal object or backing array, respectively, that is O or of which O is a subobject. [ Note: A pointer value obtained by pointer arithmetic (7.6.6 [expr.add]) from a pointer value associated with an evaluation E is also associated with E. -- end note ]

    A pointer value P is valid in the context of an evaluation E if ...

  2. Add a bullet after 7.7 [expr.const] bullet 10.25 as follows:

    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:
    • ...
    • a three-way comparison (7.6.8 [expr.spaceship]), relational (7.6.9 [expr.rel]), or equality (7.6.10 [expr.eq]) operator where the result is unspecified;
    • an equality operator comparing pointers to potentially non-unique objects, if the pointer values of both operands are associated with different evaluations (6.8.4 [basic.compound]) and they can both point to the same offset within the same potentially non-unique object; [ Example:
        constexpr const char *f() { return "foo"; }
      
        constexpr bool b1 = "foo" == "foo";   // error: non-constant
        constexpr bool b2 = f() == f();       // error: non-constant
        constexpr const char *p = f();
        constexpr bool b3 = p == p;           // OK, value of b3 is true
        constexpr bool b4 = "xfoo" + 1 == "foo\0y"; // error: non-constant; string literal object could contain "xfoo\0y"
        constexpr bool b5 = "foo" == "bar";   // OK, value of b5 is false
        constexpr bool b6 = "foo" == "oo";    // OK, value of b6 is false; offsets would be different in a merged string literal object
      
      -- end example ]
    • ...