Существуют ли точки последовательности в фигурных списках инициализаторов, когда они применяются к конструкторам?

Согласно стандартному документу n4296 C ++:

[dcl.init.list] (8.5.4.4) (pg223-224)

В пределах списка инициализатора списка фигурных скобок предложения инициализатора, включая любые, которые являются результатом расширений пакета (14.5.3), оцениваются в порядке, в котором они появляются. То есть каждое вычисление значения и побочный эффект, связанный с данным предложением инициализатора, упорядочивается перед каждым вычислением значения и побочным эффектом, связанным с любым предложением инициализатора, которое следует за ним в списке через запятую списка инициализатора.[Примечание: этот порядок оценки выполняется независимо от семантики инициализации; например, он применяется, когда элементы списка инициализатора интерпретируются как аргументы вызова конструктора, хотя обычно нет никаких ограничений последовательности аргументов вызова. —Конечная записка]

(акцент мой)

Примечание было добавлено здесь:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1030

Это читает мне, что следующий код:

#include <iostream>

struct MyType {
  MyType(int i, int j, int k, int l)
    : sum(i + j + k + l)
  {

  }

  int sum;
};

int main()
{
  int i = 0;
  std::cout << MyType{ ++i, ++i, ++i, ++i }.sum << '\n';
}

Должно быть напечатано «10».

Это мое рассуждение:

MyType инициализируется через список фигурных скобокБрекеты-init-списки оцениваются в порядкедаже когда этоинтерпретируется как аргументы вызова конструктораэто означает, что он должен оцениваться как MyType (1,2,3,4)

То есть приведенный выше код должен вести себя точно так же, как этот код:

#include <initializer_list>
#include <iostream>

int main()
{
  int i = 0;
  std::initializer_list<int> il{++i, ++i, ++i, ++i};
  std::cout << *il.begin() + *(il.begin() + 1) + *(il.begin() + 2) + *(il.begin() + 3) << '\n';
}

Но это не так. Первый пример печатает «16», а второй пример печатает «10»

Буквально каждый компилятор от каждого поставщика, которому я могу достать отпечатки «16»,по-видимому игнорируя эту часть стандарта и не вставляя точки последовательности.

Что мне здесь не хватает?

Примечание: следующее, кажется, связано с этим вопросом:

(Оптимизация?) Ошибка, связанная с GCC std :: threadhttps://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253

Ответы на вопрос(2)

Ваш ответ на вопрос