The initializer_list object returned to function is broken. See the next code: #include<initializer_list> #include<iostream> std::initializer_list<int> f(int a, int b) { return {a, b}; } int main() { std::initializer_list<int> list = f(0, 1); for(int i: list) std::cout << i << std::endl; } Output result (example) is 2293416 2293636 It's a strange result. Output should be 0 1 I tried use compiler version 4.6.0 Release and 4.7.0 20110521 (experimental)
If we *really* have to use the word broken here, it much better applies to your snippet, not the implementation of std::initializer_list: an initializer_list is essentially just a pointer (+ a length) into something else (open the header and you will see it): thus, f is returning a pointer to the {a, b} which by itself goes away when f returns. Anything can happen. Compare: std::initializer_list<int> f(int a, int b) { static auto range = {a, b}; return range; } ...
There's a note in [support.initlist] which says: "Copying an initializer list does not copy the underlying elements." However there was some discussion on the core reflector last month pointing out that other requirements are inconsistent with that.
Hi All, Would anyone from GCC team please confirm, when the broken initializer_list feature will be fixed: I tried with gcc 4.6.3 and it appears to be broken today. Results: Behaviour is persistent and data returning from caller constructor were garbage values. $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper Target: i686-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu Thread model: posix gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
This is not a bug in GCC, there's nothing to fix.
Hi Jonathan Wakely, Just wanted to confirm the doubt: Do you wanted to mean that, the initializer_list<T> behaviour is exactly like this(work for local stack members) and there nothing work around possible to avoid this observation ? Thanks in advance, Joyabrata Ghosh
(In reply to comment #5) > Hi Jonathan Wakely, > > Just wanted to confirm the doubt: That's not a "doubt" it's a question. > Do you wanted to mean that, the initializer_list<T> behaviour is exactly like > this(work for local stack members) and there nothing work around possible to > avoid this observation ? Yes. If you want to pass data out of a function use a container or a tuple or something that *copies* the data. An std::initializer_list is not a container, it does not own or copy its elements. The workaround is don't misuse initializer_list for something it isn't designed to do.
I think this should be reopened. The return value object, which exists in the calling scope, is initialized from the braced-init-list. No copying occurs beyond what is demonstrated in the example in [dcl.init.list]/6. For more detail, see http://stackoverflow.com/q/15286450/153285 .
Oops, I didn't read the original code closely enough. To be OK by the above interpretation, the local initializer_list variable would need to be eliminated from main() and the loop would be for(int i: f()) Should I open a new bug?