4

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
manlio
  • 16,658
  • 13
  • 67
  • 107
Adib
  • 657
  • 5
  • 19
  • 4
    Your code doesn't contain any initializer lists. – Kerrek SB May 16 '16 at 13:14
  • 3
    Evaluation order of function parameters is unspecified in C++. – 101010 May 16 '16 at 13:14
  • http://stackoverflow.com/questions/621542/compilers-and-argument-order-of-evaluation-in-c – ATul Singh May 16 '16 at 13:16
  • 5
    Note to all commenting and duplicate voters: The OP isn't calling a function with two arguments, the OP is calling a function with *one* argument, a vector which is initialized using uniform initialization and the `std::initializer_list` constructor of the vector. – Some programmer dude May 16 '16 at 13:21
  • @KerrekSB consider edited post – Adib May 16 '16 at 13:21
  • @user5905343 Can you please tell us what compiler you are using? And what version of it? – Some programmer dude May 16 '16 at 13:23
  • I'm removing the duplicate (never mind, got beaten to it) because the OP changed the question to match the original title, which I'm also restoring. However, @OP, neither GCC, nor Clang, give me that output with your revised post. Could you post more information about where you obtained this result? – chris May 16 '16 at 13:23
  • Looks like a compiler bug to me. Which compiler are you using, what are the compiler args? I am going to give OP 5-10 minutes to respond, and then I will VTC as unclear. – SergeyA May 16 '16 at 13:25
  • 1
    Did you run the code in the edited post, or is this the result from the previous version? – interjay May 16 '16 at 13:25
  • @JoachimPileborg why they vote down when they dont understand question – Adib May 16 '16 at 13:26
  • @user5905343, what you are saying seems extremely unlikely. I am giving you the benefit of the doubt, but not for long. – SergeyA May 16 '16 at 13:27
  • MSVC 19 results in `fg` as well (tested on http://rextester.com/l/cpp_online_compiler_visual) – Brandlingo May 16 '16 at 13:27
  • @user5905343 Your original question had code different from what was being asked. The edited question is unreproducible on 3 popular compilers and you are not providing info on compiler you have used, so commenters are skeptical about the correctness. – Zdeslav Vojkovic May 16 '16 at 13:28
  • @SergeyA consider there is just one argument in function call – Adib May 16 '16 at 13:28
  • @user5905343, yes, there is one argument, no one is disputing that. I asked you specific question, can you answer it? – SergeyA May 16 '16 at 13:29
  • @ZdeslavVojkovic I'm compiling With Gcc on Eclipse and i have no Error – Adib May 16 '16 at 13:30
  • Does "I have no error" mean that you actually get `fg` as result? – Zdeslav Vojkovic May 16 '16 at 13:31
  • @ZdeslavVojkovic , I mean i don't have compile Error but i expect according standard to get " fg " but i have " gf " on output – Adib May 16 '16 at 13:34
  • 2
    Which exact version of GCC are you using? – Zdeslav Vojkovic May 16 '16 at 13:34
  • @ZdeslavVojkovic gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 – Adib May 16 '16 at 13:36
  • could be this: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253 – Zdeslav Vojkovic May 16 '16 at 13:38
  • @KerrekSB Why is it not an init-list? AFAIK an init-list initializes an object. And isn't this what's happening here with the init-list `{f(), g()}` initializing the vector? Am I missing something? – KeyC0de Oct 06 '18 at 18:52
  • @Nik-Lz: The question has since been edited, the comment no longer applies. – Kerrek SB Oct 07 '18 at 00:06
  • @KerrekSB Ah alright. Thanks. But just to note that this `{f(), g()}` is an initializer list. – KeyC0de Oct 07 '18 at 01:30
  • @Nik-Lz: Yes, thanks, I realize that. The comment served no other purpose than to get the OP to fix the question at a time where the question was unclear. – Kerrek SB Oct 07 '18 at 12:21

2 Answers2

2

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).
Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989
  • Probably I'm wrong but a *braced-init-list* may appear in many other contexts: e.g. *for-range-initializer* (`for (for-range-declaration: braced-init-list) statement`, §6.5.4), *jump-statements* (`return braced-init-list;`, §6.6), ... – manlio May 16 '16 at 15:21
  • @manlio: Meh, okay well I did try to find the proof that _this_ case doesn't have a _braced-init-list_ in it (which would be a much better answer) but concluded I'd have to quote too much. – Lightness Races in Orbit May 16 '16 at 15:22
  • Also considering [std::initializer_list as function argument](http://stackoverflow.com/q/2357452/3235496) and especially the [this answer](http://stackoverflow.com/a/2357688/3235496), argument passing is supposed to have the same meaning as `=` initializer (both is copy initialization). So isn't this copy initialization (object *list-initialized* via *braced-init-list*)? – manlio May 16 '16 at 15:30
  • @manlio: Haven't got a moment to investigate right now. Feel free to write an answer :) – Lightness Races in Orbit May 16 '16 at 15:33
0

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).

Community
  • 1
  • 1
manlio
  • 16,658
  • 13
  • 67
  • 107
  • i tried both in any case result is the same problrm isnt adding --std=c++11 – Adib May 16 '16 at 13:45
  • @user5905343 unfortunately gcc v4.8.4 is missing on https://gcc.godbolt.org but considering the above tests it seems a bug. – manlio May 17 '16 at 07:57