<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.msonormal0, li.msonormal0, div.msonormal0
{mso-style-name:msonormal;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
span.EmailStyle18
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I can definitely see maintaining a restricted include set to be burdensome I will have to think on how to address that in a reasonable way. Your clang-tidy suggestion may be useful
here.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I don't think maintaining a restricted use of features will be particularly hard though. For <array>, <tuple>, <utility>, and <algorithm>, do you foresee changes where an existing
function doesn't throw, but starts to throw? Or doesn't currently allocate, but starts to allocate? If we were talking about the containers, or iostreams, or regex, I would definitely agree that the implementation flexibility is needed. I'm not sure I agree
when it's a smaller list of low level headers though.<o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I agree with your examples. Existing functions are unlikely to suddenly require exceptions or allocations. However it is conceivable that <tuple> or <utility> could require some internals, which themselves don't allocate or throw, that
were previously only used by restricted features, or that live in restricted headers. For example libc++ often uses unique_ptr as a scope guard, but the class is primarily used to deal with dynamically memory and likely wouldn't be a part of freestanding mode.
Forbidding its use in freestanding features could quickly become problematic. (Note: <algorithm> already widely depends on unique_ptr for this purpose).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I posit that the implementation requires the general freedom to use classes not supported in freestanding mode. We'll likely be able to strike a balance between what the implementation needs and what freestanding users expect, but there
needs to be leeway; Leeway that restricting entire headers in freestanding mode does not provide.<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Unique_ptr is a strange beast for exactly the reasons you describe. I’m tempted to include it in a freestanding definition, but it would definitely feel odd pulling it along, but not taking make_unique, and not allowing the default deleter.
I think I also agree that restricting by header is too blunt of an instrument to validate the freestanding restrictions.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> I think it would be much better to get as much of libc++ compiling as possible, even if it depends on restricted<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> features, and then finding another mechanism to restrict the features end-users are allowed to use (Such as clang-tidy).<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> This would eliminate the need to restructure headers or spam out internal #ifdef guards.<o:p></o:p></p>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">One thing I want to avoid is turning straightforward mistakes into errors that are even more cryptic than what C++ users have grown accustomed to. I don't really want the failure
condition of inplace_merge to be a linker error complaining about a missing operator new. clang-tidy might help with that. #ifdefs are a straightforward way to address that concern, though it requires a substantial amount of effort. Would you be opposed
to widespread static_asserts?<o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">What kind of static asserts? Can you provide an example? <o:p></o:p></p>
</div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">What I had in mind here was for the first line of inplace_merge (and other allocating algorithms) to be something along the lines of static_assert(!_LIBCPP_HAS_NO_ALLOC).
I think you had a much better suggestion though…<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><o:p> </o:p></span></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">>> * I'll also need to figure out how to not drag along unwanted header dependencies.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> I don't see how libc++ could upstream changes since it requires every header<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> it currently includes (modulo bugs).<o:p></o:p></p>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The straightforward (and labor intensive) way is with #ifdef _LIBCPP_HAS_NO_ALLOC<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">_LIBCPP_HAS_NO_ALLOC is exactly the invasive change I wanted to avoid. First <new> is currently a freestanding header,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">and I think it should stay that way. Second I want to avoid the maintenance cost of such a restrictive<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">configuration. This macro would have to guard the the vast majority of the library, unlike<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">_LIBCPP_HAS_EXCEPTIONS and _LIBCPP_NO_RTTI which have a much smaller and more manageable scope.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If the end goal is simply to diagnose when end users use features that dynamically allocate I suspect there<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">are less invasive ways to do it. First there are two important things to note:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">(1) Libc++ has very few naked new/delete calls. Almost all dynamic allocations go through std::allocator.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">(2) std::allocator is typically used in dependent contexts (templates). <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Instead of #ifdef'ing out std::allocator and everything that uses it, we could make instantiating std::allocator::allocate<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">produce a diagnostic. This would make the changes needed within libc++ significantly smaller while still<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">producing reasonable diagnostics when users attempt to use those types.<o:p></o:p></p>
</div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">Putting a static assert (or some other kind of diagnostic) in std::allocator::allocate seems like an excellent idea to me. I’d also want to hunt down the other places where
raw new is used, but I think this approach has a lot of promise. We can document what we officially support, but say that other things might work. If someone instantiates code that hits std::allocator, they will get a static assert. If they write their
own code that calls new or delete, they will get a linker error (in the Windows Kernel at least). If they write their own allocator that uses ExAllocatePoolWithTag, or malloc, or whatnot, then that’s fine, they will just need to be super careful that they
don’t shoot themselves in the foot with std::list gotchas.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> Using hard-coded kernel paths is not a change I see being upstream-able. However<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> we might be able to convince MSVC to implement #include_next if we can provide<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> strong enough rational for why we need it.<o:p></o:p></p>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">These wouldn't be hard coded paths. The code would look something like...<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">#if __LIBCPP_HAS_INCLUDE_NEXT<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">#include_next <limits.h><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">#else<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">#include __LIBCPP_HACK_INCLUDE_NEXT(limits.h)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">#endif<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">__config would have the definition of __LIBCPP_HACK_INCLUDE_NEXT, and
<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><a href="http://config_site.in" target="_blank">config_site.in</a> would have the relative path needed to glue everything together ("../../km/crt" in my case).<o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">That sounds like a fairly reasonable solution. Although aren't macro expansions inside #include directives UB?<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">The GCC docs claim it is implementation-defined behavior (
<a href="https://gcc.gnu.org/onlinedocs/cpp/Computed-Includes.html">https://gcc.gnu.org/onlinedocs/cpp/Computed-Includes.html</a> ). I haven’t done the research in the spec to know for sure. STLPort does it though, and the computed include hackery there seems
to work fine for lots of versions of GCC, Clang, MSVC, and I think even Intel’s compiler.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><o:p> </o:p></span></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> I'm violently against working around MSVC template bugs. Every time I've seen<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">> it done it makes the implementation worse.<o:p></o:p></p>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">That's fair. I will say that not _all_ of the workarounds make worse code,<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">but quite a few do. This may end up being what forces me to MSVC 2017.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">One example of a workaround that I don't think made things worse...<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail {<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> template <class ...><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">- static constexpr bool __enable_default() { return false; }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">+ static constexpr bool __enable_default = false;<o:p></o:p></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Your example uses C++14 variable templates, which I don't think you intended because MSVC 2015 doesn't support<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">them either.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Ironically that's a perfect example of a change that would make things drasticly worse.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">First the suggested fix cannot be applied because variable templates are C++14 features.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Second we couldn't use a non-template in this case because it's important that the result is<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">type dependent in the non-fail cases to prevent eager SFINAE evaluation.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">The <tuple> SFINAE is very complicated and it's full of subtle but important details.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">It can barely manage it with a fully conforming C++11 compiler.<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><o:p> </o:p></span></p>
<p class="MsoNormal">I almost didn’t include an example at all, because this was going to be the inevitable outcome, especially since I picked something involving std::tuple.<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><o:p> </o:p></span></p>
</div>
</div>
</body>
</html>