Adib
Adib

Reputation: 723

Evaluation order of elements in an initializer list

Why is function g() called first? I defined g() as the second element in the initializer list.

Is the following quote from the standard, relating to initializer-lists, relevant?

§8.5.4.4: 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.

#include <iostream>
#include <vector>

int f() { std::cout << "f"; return 0;}
int g() { std::cout << "g"; return 0;}

void h(std::vector<int> v) {}

int main() {

   h({f(), g()});
}

Output:

gf

Upvotes: 5

Views: 1966

Answers (2)

manlio
manlio

Reputation: 18902

It seems to me that the quote is relevant (the compiler sees an initializer list):

8.5/14,16:

The initialization that occurs in the form

T x = a;

as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization.

.

.

The semantics of initializers are as follows[...]: If the initializer is a braced-init-list, the object is list-initialized (8.5.4).

(more details in std::initializer_list as function argument and Folds (ish) In C++11)

Moreover any {}-list should be sequenced (the standard uses a very strong wording about this fact. See also http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1030).

So it's probably a GCC bug (fixed after gcc v4.9.0).

Indeed, trying various GCC version, I get:

GCC      with --std=c++11   without (--std=c++98)
4.7.3        fg                    gf  <-
4.8.1        fg                    gf  <-
4.8.2        fg                    gf  <-
4.9.0        fg                    gf  <-
4.9.2        fg                    fg
5.1.0        fg                    fg
5.2.0        fg                    fg
6.1.0        fg                    fg

Extended initializer lists are only available with C++11 but GCC compiles the code anyway (with a warning, e.g. see gcc -Wall -Wextra vs gcc -Wall -Wextra -std=c++11).

Upvotes: 1

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385098

This is not a braced-init-list, so that rule does not apply.

[C++14: 5.17/9]: A braced-init-list may appear on the right-hand side of

  • an assignment to a scalar, in which case the initializer list shall have at most a single element. The meaning of x={v}, where T is the scalar type of the expression x, is that of x=T{v}. The meaning of x={} is x=T{}.
  • an assignment to an object of class type, in which case the initializer list is passed as the argument to the assignment operator function selected by overload resolution (13.5.3, 13.3).

Upvotes: 3

Related Questions