https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85873
Jason Merrill <jason at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords|wrong-code |missed-optimization Depends on| |67445 --- Comment #2 from Jason Merrill <jason at gcc dot gnu.org> --- This is actually only a missed optimization, your code has undefined behavior. 11.6.4 [dcl.init.list]: An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation generated and materialized (7.4) a prvalue of type “array of N const E”, where N is the number of elements in the initializer list.... The array has the same lifetime as any other temporary object (15.2), except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary.... [ Note: The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated. — end note ] So the array's lifetime only lasts until the end of the return-statement; when the function returns, the array is gone, and so the range for iterates a dangling pointer. As the note says, a compiler is permitted to put it in .rodata as an optimization, just as it can for const int ar[] = { 1,2,3 }; but it isn't required to do so. Bug 67445 asks for a warning about this situation, which I have now implemented and will check in before long. Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67445 [Bug 67445] New warning: returning std::initializer_list bound to temporary