Title
Iterating expansion statements woes
Status
open
Section
8.7 [stmt.jump]
Submitter
Jakub Jelinek

Created on 2025-07-08.00:00:00 last changed 3 weeks ago

Messages

Date: 2025-07-08.00:00:00

(From submissions #725 and #730.)

The rewrite of iterating expansion statements contains:

  static constexpr auto iter = begin + i;
where the type of i is unspecified, but overload resolution of + depends on the type of i.

Furthermore, the rewrite contains

  for (auto i = begin ; i != end ; ++i, ++result);
which might invoke an overloaded comma operator, which is undesirable.

Furthermore, because of the use of static in the rewrite, the example in 8.7 [stmt.jump] paragraph 7 is ill-formed.

Possible resolution:

  1. Change in 8.7 [stmt.jump] bullet 5.2 as follows:

    Otherwise, if S is an iterating expansion statement, S is equivalent to:
      {
        init-statement
        static constexpr auto&& range = expansion-initializer ;
        static constexpr auto begin = begin-expr;    // see 8.6.5 [stmt.ranged]
        static constexpr auto end = end-expr;        // see 8.6.5 [stmt.ranged]
        S0
        .
        .
        .
        SN-1
      }
    
    where N is the result of evaluating the expression
      [] consteval {
        std::ptrdiff_t result = 0;
        for (auto i = begin ; i != end ; ++i, ++result) ++result;
        return result;    // distance from begin to end
      }()
    
    and Si is
      {
        static constexpr auto iter = begin + i i;
        for-range-declaration = *iter ;
        compound-statement
      }
    
    The variables range , begin , end , and iter are defined for exposition only. The identifier i is considered to be a prvalue of type std::ptrdiff_t. [Note 1 : The instantiation is ill-formed if range is not a constant expression (7.7 [expr.const]). -- end note]
  2. Change in 8.7 [stmt.jump] paragraph 7 as follows:

    [ Example 2:
      consteval int f() {
        static constexpr std::array<int, 3> arr {1, 2, 3};
        int result = 0;
        template for (constexpr int s : arr) {      // OK, iterating expansion statement
          result += sizeof(char[s]);
        }
        return result;
      }
      static_assert(f() == 6);
    
    end example]
Drafting note: Instead of the second change, a more preferrable change might be to remove the statics in the rewrite.
History
Date User Action Args
2025-07-08 00:00:00admincreate