2

Is the comma (,) a sequence point in std::initializer_list?


example: is this UB or not:

#include <vector>

int main() 
{
    auto nums = []
    {
        static unsigned x = 2;
        return ( x++ % 2 ) + 1;
    };

    std::vector< int > v{ nums(), nums(), nums(), nums(), nums() };
    // not sure if this is different: (note the additional brackets)
    // std::vector< int > v({ nums(), nums(), nums(), nums(), nums() });
    for( auto i : v )
    {
        std::cout << i;
    }

    return 0;
}
Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
  • 2
    There are no "sequence points" any more in C++11. However, the order of evaluation is guaranteed and it is indeed ordered, but I'll search for a duplicate first before answering. – dyp Nov 28 '13 at 12:28
  • @DyP - thanks. I didn't find duplicate, although I'm pretty sure I've seen similar question.. I'm almost sure, the order is guaranteed, but not 100%. – Kiril Kirov Nov 28 '13 at 12:29
  • 1
    [dcl.init.list]/4 "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*." – dyp Nov 28 '13 at 12:30
  • @DyP - "There are no "sequence points" " - seriously? That's interesting.. Thanks for the quote - if you add it as an answer, I'll accept it. – Kiril Kirov Nov 28 '13 at 12:30
  • 1
    @Kiril: Yeah, it's a notion of "sequenced-before" and "sequenced-after", now. – Lightness Races in Orbit Nov 28 '13 at 12:32
  • It's high time for me to take a deeper look at the new standard, obviously. This sounds like a dramatic change to me. – Kiril Kirov Nov 28 '13 at 12:33
  • Possible duplicates, for example: http://stackoverflow.com/q/14442894/420683 http://stackoverflow.com/q/20186084/420683 You'd need to search for *list-initialization* (not `std::initializer_list`), because that's where the order is defined. – dyp Nov 28 '13 at 12:34
  • @DyP - I searched, but everything I saw was about the constructor initialization list. The questions is a bit different, I think (variadic templates and this case here), but I'm not 100% positive. – Kiril Kirov Nov 28 '13 at 12:37
  • 1
    Also search for the [c++11] tag ;) To answer the question in the code comment: No, it's not different. It's list-initialization in both cases, so the same rules apply wrt sequencing. The second one *could* have a different meaning (in a general case), but is has the same meaning here: Call the `initializer_list` constructor of `vector` with an `initializer_list` constructed via list-initialization. – dyp Nov 28 '13 at 12:39
  • Also note `std::generate_n`, it's a bit more programatical then just copying and pasting `num()` `n` times.http://en.cppreference.com/w/cpp/algorithm/generate_n – 111111 Nov 28 '13 at 12:44
  • @111111 - yes, yes, this was just an example for the (obviously outdated) "sequence points". – Kiril Kirov Nov 28 '13 at 12:47
  • @KirilKirov okay. Just making sure; it's an interesting question non the less. – 111111 Nov 28 '13 at 12:48

1 Answers1

4

According to C++11 § 8.5.4 [dcl.init.list] paragraph 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. 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.

As far as I know GCC 4.8.1 has a bug relative to evaluation of initializers. I described it here

http://cpp.forum24.ru/?1-3-0-00000063-000-0-0-1378892425

Though the text is written in Russion but it can be simply translated in English by using for example google translate.

Casey
  • 41,449
  • 7
  • 95
  • 125
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335