[LLVMbugs] [Bug 18207] New: warnings could help for improper use of std::initializer_list

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Dec 10 21:14:48 PST 2013


http://llvm.org/bugs/show_bug.cgi?id=18207

            Bug ID: 18207
           Summary: warnings could help for improper use of
                    std::initializer_list
           Product: clang
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C++11
          Assignee: unassignedclangbugs at nondot.org
          Reporter: oneill+llvmbugs at cs.hmc.edu
                CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified

There are some subtle gotchas people can encounter when using C++11's
std::initializer_list.  Unfortunately, it seems that clang doesn't warn for
them.

In particular, the code below has undefined behavior, but produces no warnings
when compiled with clang++. 

--snip--
#include <iostream>          // std::cout
#include <initializer_list>  // std::initializer_list

std::initializer_list<int> ilist_func()
{
    return { 10, 20, 30 };
    // ^-- this is not directly creating the return value, instead this
    // statement creates a temporary initializer list, which is then *copied*
to
    // the return value.
}

int main ()
{
    std::initializer_list<int> mylist = ilist_func();
    std::cout << "mylist contains:";
    for (int x: mylist)
        std::cout << ' ' << x;
    std::cout << '\n';
    return 0;
}
--snip--

For example, on OS X this program produces the output

mylist contains: 32767 0 0

The problem with this code is that the return statement results in a call to
the std::initializer_list copy constructor, and as defined in 18.9
[support.initlist], “Copying an initializer list does not copy the underlying
elements”.  (There is also an additional copy in the initialization of mylist,
but that could be avoided by using an rvalue reference.)

It would be really awesome if clang warned about this code much as it does for
returning pointers/references to local variables.


Also, I may be mistaken here, but I'm left wondering if this code is also
problematic, since it also involves a call to the std::initializer_list copy
constructor.

--snip--
#include <iostream>          // std::cout
#include <initializer_list>  // std::initializer_list

int main ()
{
    std::initializer_list<int>&& mylist = { 10, 20, 30 };
    // ^-- the temporary initializer list is out of scope now
    std::cout << "mylist contains:";
    for (int x: mylist)
        std::cout << ' ' << x;
    std::cout << '\n';
    return 0;
}
--snip--

and likewise

--snip--
#include <iostream>          // std::cout
#include <initializer_list>  // std::initializer_list

int main ()
{
    std::initializer_list<int>&& mylist;
    mylist = { 10, 20, 30 };
    // ^-- the temporary initializer list is out of scope now
    std::cout << "mylist contains:";
    for (int x: mylist)
        std::cout << ' ' << x;
    std::cout << '\n';
    return 0;
}
--snip--

The above code is found online as an example on how to use
std::initializer_list, here:
http://www.cplusplus.com/reference/initializer_list/initializer_list/initializer_list/

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20131211/60e5b84b/attachment.html>


More information about the llvm-bugs mailing list