Order of evaluation of elements in initializer-list

55 views
Skip to first unread message

Vlad from Moscow

unread,
Sep 10, 2013, 6:18:04 PM9/10/13
to std-dis...@isocpp.org
I tried the following test program with GCC 4.8.1 at www.ideone.com
 
[code]
#include <utility>
#include <iostream>
int main()
{
 int x = 0;
 
 std::pair<int, int> p { ( x = 10 ), x + 10 };
 std::cout << p.first << '\t' << p.second << std::endl;
 
 return 0;
}
[/code]
 
and I got the following result
 
10   10
 
Am I right that it is a bug of the compiler and the correct result should be 10 20 or I missed something?
 
 

Richard Smith

unread,
Sep 10, 2013, 6:28:45 PM9/10/13
to std-dis...@isocpp.org
Yes, that's a compiler bug, and still seems to be present in a recent g++ trunk checkout. Clang produces '10      20' as expected (in C++11 mode).

Vlad from Moscow

unread,
Sep 11, 2013, 5:31:28 AM9/11/13
to std-dis...@isocpp.org
It seems that the problem of the compiler is that it evaluates initializer-clauses from right to left applying side effects. For example the output of the following test program
 
[code]
#include <utility>
#include <iostream>
int main()
{
 int x = 0;
 
 std::pair<int, int> p { x + 10, x++ };

 std::cout << p.first << '\t' << p.second << std::endl;
 
 return 0;
}
[/code]
 
is
 
11 0
 
though the correct result should be
 
10 10

среда, 11 сентября 2013 г., 2:28:45 UTC+4 пользователь Richard Smith написал:

Vlad from Moscow

unread,
Sep 11, 2013, 5:34:11 AM9/11/13
to std-dis...@isocpp.org
I am sorry I have made a typo. :)
 
The correct resuslt will be
 
10 0

среда, 11 сентября 2013 г., 13:31:28 UTC+4 пользователь Vlad from Moscow написал:

Xeo

unread,
Sep 11, 2013, 5:58:40 AM9/11/13
to std-dis...@isocpp.org
Yes, GCC doesn't yet evaluate braced-init-lists left-to-right as demanded by the standard. Surprisingly, it *does* evaluate aggregate-init left-to-right.

David Krauss

unread,
Sep 12, 2013, 5:21:20 AM9/12/13
to std-dis...@isocpp.org


On Wednesday, September 11, 2013 5:58:40 PM UTC+8, Xeo wrote:
Yes, GCC doesn't yet evaluate braced-init-lists left-to-right as demanded by the standard. Surprisingly, it *does* evaluate aggregate-init left-to-right.

To be sure, aggregate initialization is just one semantic that may be selected to interpret the braced-init-list syntax.

It probably maps the braced-init-list directly to a normal function argument list and forgets the special semantics. IIRC aggregate initializers are sequenced since C++98.
Reply all
Reply to author
Forward
0 new messages