Bug 49122 - [C++0x] initializer_list is broken
Summary: [C++0x] initializer_list is broken
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-23 12:40 UTC by sscrisk
Modified: 2013-03-08 07:57 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description sscrisk 2011-05-23 12:40:44 UTC
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)
Comment 1 Paolo Carlini 2011-05-23 14:19:40 UTC
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;
}

...
Comment 2 Jonathan Wakely 2011-05-23 16:44:22 UTC
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.
Comment 3 Joyabrata Ghosh 2013-01-08 09:38:51 UTC
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)
Comment 4 Jonathan Wakely 2013-01-08 10:27:55 UTC
This is not a bug in GCC, there's nothing to fix.
Comment 5 Joyabrata Ghosh 2013-01-08 10:48:36 UTC
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
Comment 6 Jonathan Wakely 2013-01-08 12:39:26 UTC
(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.
Comment 7 David Krauss 2013-03-08 06:56:00 UTC
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 .
Comment 8 David Krauss 2013-03-08 07:57:03 UTC
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?