<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - warnings could help for improper use of std::initializer_list"
   href="http://llvm.org/bugs/show_bug.cgi?id=18207">18207</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>warnings could help for improper use of std::initializer_list
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++11
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>oneill+llvmbugs@cs.hmc.edu
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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:
<a href="http://www.cplusplus.com/reference/initializer_list/initializer_list/initializer_list/">http://www.cplusplus.com/reference/initializer_list/initializer_list/initializer_list/</a></pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>