https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121434

            Bug ID: 121434
           Summary: spurious -Wsequence-point warning
           Product: gcc
           Version: 15.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jylefort at gmail dot com
  Target Milestone: ---

```
#include <format>
#include <string>
#include <tuple>

inline std::string whatever (int index, auto&& arg) {
    return std::format("{}: {}", index, std::forward<decltype(arg)>(arg));
}

template <class... Args>
inline auto foo (Args&&... args) {
    int index = 0;
    return std::tuple{whatever(index++, std::forward<Args>(args))...};
}

inline void bar() {
    foo(123, "xyz");
}
```

Compile with:

```
$ g++ -std=c++23 -Wall -Wextra -c test.cxx
test.cxx: In instantiation of ‘auto foo(Args&& ...) [with Args = {int, const
char (&)[4]}]’:
test.cxx:16:8:   required from here
   16 |     foo(123, "xyz");
      |     ~~~^~~~~~~~~~~~
test.cxx:12:69: warning: operation on ‘index’ may be undefined
[-Wsequence-point]
   12 |     return std::tuple{whatever(index++, std::forward<Args>(args))...};
      |                                                                     ^
test.cxx:12:69: warning: operation on ‘index’ may be undefined
[-Wsequence-point]
```

This warning is spurious. In a braced-init-list, the order of evaluation of the
param pack expansion is indeed defined.

```
Within the initializer-list of a braced-init-list, the initializer-clauses,
including any that result from pack expansions, are evaluated in the order in
which they appear. That is, every value computation and side effect associated
with a given initializer-clause is sequenced before every value computation and
side effect associated with any initializer-clause that follows it in the
comma-separated list of the initializer-list. [ Note: This evaluation ordering
holds regardless of the semantics of the initialization; for example, it
applies when the elements of the initializer-list are interpreted as arguments
of a constructor call, even though ordinarily there are no sequencing
constraints on the arguments of a call.  — end note ] 
```

Source: https://timsong-cpp.github.io/cppwp/n4659/dcl.init.list#4

Reply via email to