lundi 25 avril 2016

Are there sequence points in braced initializer lists when they apply to constructors?

According to the n4296 C++ standard document:

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

Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions (14.5.3), 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 ]

(emphasis mine)

The note was added here: http://ift.tt/1rdFxtu

This reads to me that the following code:

#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';
}

Should print "10".

This is my reasoning:

  • MyType is being initialized via a braced-init-list
  • braced-init-lists are evaluated in order
  • even when it is interpreted as arguments of a constructor call
  • this means that it should be evaluated as MyType(1,2,3,4)

That is to say, the above code should behave exactly like this code:

#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';
}

But it does not. The first example prints '16' and the second example prints '10'

Literally every compiler from every vendor that I can get my hands on prints '16', seemingly ignoring that part of the standard and not inserting sequence points.

What am I missing here?

Note: The following seem to be related to this question:

Aucun commentaire:

Enregistrer un commentaire