<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jun 29, 2018, at 20:50, Eric Fiselier <<a href="mailto:eric@efcs.ca" class="">eric@efcs.ca</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, Jun 29, 2018 at 11:18 AM, Louis Dionne via cfe-dev <span dir="ltr" class=""><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hey folks,<br class="">
<br class="">
Before I ask my question, let me quickly introduce myself since this is my first post. My name's Louis Dionne and I just started a new job where my main focus will be on libc++. I'm also involved in Boost (Boost.Hana), the C++ Standards Committee, and I sometimes go to C++ conferences. I'm very excited about contributing to LLVM and I'm looking forward to interacting with members of the community.<br class="">
<br class="">
With that being said, I have a simple question about potentially diagnosing the use of incomplete types in standard library containers. As you may know, the Standard currently disallows instantiating most standard library components with incomplete types. If I'm reading this right, it's actually UB to do that. From [res.on.functions] <a href="http://20.5.4.8/2" rel="noreferrer" target="_blank" class="">20.5.4.8/2</a>:<br class="">
<br class="">
> In particular, the effects are undefined in the following cases:<br class="">
> [...]<br class="">
> - if an incomplete type is used as a template argument when<br class="">
> instantiating a template component, unless specifically allowed<br class="">
> for that component.<br class="">
<br class=""></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Note that some containers explicitly allow incomplete types. Specifically forward_list, list, and vector. (See N4510).<br class=""></div><div class="">IIRC the reason the other node based containers weren't added was because some implementations were unable</div><div class="">to support such a change without taking an ABI break.</div></div></div></div></div></blockquote><div><br class=""></div><div>This is the list I could gather (some of them have requirements on the allocator being a complete allocator):</div><div><div><br class=""></div><div>- unique_ptr (23.11.1/5)</div><div>- default_delete (23.11.1.1.1/2)</div><div>- shared_ptr (23.11.3/2)</div><div>- weak_ptr (23.11.4/2)</div><div>- enable_shared_from_this (23.11.6/3)</div><div>- atomic<> specializations for smart pointers (23.11.8/1)</div><div>- all the type traits (23.15.2/2)</div><div>- forward_list (26.3.9.1/4)</div><div>- list (26.3.10.1/3)</div><div>- vector (26.3.11.1/3)</div><div><br class=""></div><div><br class=""></div></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
libc++ currently does not always warn or trigger a compilation error for such uses. Sometimes it "works", sometimes it doesn't. Does anybody know whether it would be harmful to diagnose this UB by triggering a compilation error when a standard library component that does not allow it is instantiated with an incomplete type?</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="">
Specifically, what I'm wondering is whether libc++ actually supports this use case (despite it being banned from the Standard), and users are relying on it. If that were the case, I wouldn't want to break people's code for the sake of blindly sticking more closely to the spec, and we could instead change the Standard to make this use case implementation-defined or even well-defined.<br class=""></blockquote><div class=""><br class=""></div><div class="">Yes, libc++ explicitly attempts to support this case and there are users relying on it. See the `incomplete_type.pass.cpp` tests under `test/std/containers`.</div><div class=""><br class=""></div><div class="">Normally there is no need to eagerly diagnose incomplete types, as they'll be diagnosed in their own time when a complete type is actually needed (in the case of containers),</div><div class="">The problematic cases are those which result in ODR violations, such as instantiating a type trait twice, with an incomplete type and then later the completed type.</div></div></div></div></div></blockquote><div><br class=""></div><div>Thanks — this is exactly the kind of background information I wanted! In this case, would it make sense to change the Standard so that it is implementation-defined whether template components of the standard library can be instantiated with incomplete types? Or at least the containers?</div><div><br class=""></div><div>The current situation is a bit annoying in that it’s technically UB as far as the Standard is concerned, so libc++ letting its users use incomplete types is an invitation for them to get UB on other platforms.</div><div><br class=""></div><div>Louis</div></div><br class=""></body></html>