Title
Missing parentheses in expansion of fold-expression could cause syntactic reinterpretation
Status
ready
Section
13.7.4 [temp.variadic]
Submitter
Richard Smith

Created on 2022-08-05.00:00:00 last changed 1 month ago

Messages

Date: 2022-08-26.21:45:07

Proposed resolution (approved by CWG 2022-08-26):

Change in 13.7.4 [temp.variadic] paragraph 10 as follows:
The instantiation of a fold-expression (7.5.6 [expr.prim.fold]) produces:
  • ( ((E1 op E2 ) op . . . ) op EN ) for a unary left fold,
  • ( E1 op (. . . op (EN-1 op EN )) ) for a unary right fold,
  • ( (((E op E1 ) op E2 ) op . . . ) op EN ) for a binary left fold, and
  • ( E1 op (. . . op (EN-1 op (EN op E))) ) for a binary right fold.
...
Date: 2022-08-26.21:45:07

13.7.4 [temp.variadic] paragraph 10 expands a fold-expression (including its enclosing parentheses) to an unparenthesized expression. If interpreted literally, this could result in reassociation and misinterpretation of the expression. For example, given:

template<int ...N> int k = 2 * (... + N);

... k<1, 2, 3> is specified as expanding to int k<1, 2, 3> = 2 * 1 + (2 + 3); resulting in a value of 7 rather than the intended value of 12.

Further, there is implementation divergence for the following example:

#include <type_traits>
template<class ...TT>
void f(TT ...tt) {
  static_assert(std::is_same_v<decltype((tt, ...)), int&>);
}
template void f(int /*,int*/);

gcc and MSVC apply the general expression interpretation of decltype, whereas clang and icc apply the identifier special case.

History
Date User Action Args
2022-08-26 21:45:07adminsetstatus: open -> ready
2022-08-21 09:35:33adminsetmessages: + msg6896
2022-08-05 00:00:00admincreate