<div dir="ltr"><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"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><p class="MsoNormal">Even if I did use Clang though, that would only address one of the four sub-features you identified, the port to MSVC.</p></div></div></blockquote><div><br></div><div>Right, it would only address the MSVC port but that's at least one less work-item to reach the goal.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><p class="MsoNormal"><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="border:none;padding:0in">> However I have large concerns regarding the changes required for [Kernel C library] and [Kernel subset] as I suspect they won't satisfy the above requirement.<u></u><u></u></p>
</div>
<p class="MsoNormal">Understood.  This was feedback I was expecting.  Subsets and niche platforms are a maintenance burden.</p></div></div></blockquote><div><br></div><div>Libc++ has support for other niche C libraries, but that support has been mostly limited to #ifdef'ing out parts of the <cfoo> headers because the underlying C library</div><div>doesn't provide it. If supporting the Kernel C library requires only similar changes then I think those would be reasonable to accept. </div><div><br></div><div>The complexity for C library ports usually comes from locales and input/output functions. If those are no concern then I'm hopeful it will be easy to support</div><div>the Kernel C library.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><span class="">
<p class="MsoNormal"><u></u><br></p><div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="border:none;padding:0in">> <u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> First Libc++ cannot reasonably limit itself to the proposed language and library feature set since<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> it must be free to use "restricted" features within the implementation of non-restricted ones whenever<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> it is beneficial to the implementation. The burden of maintaining a working restricted feature set could<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> not fall on upstream maintainers.<u></u><u></u></p>
</div>
</span><p class="MsoNormal">I'm not going to make any promises... but would a public build bot address your concerns?  What if the restricted feature set got standardized as the C++2x definition of a freestanding implementation?</p></div></div></blockquote><div><br></div><div>A public buildbot would be a requirement, and I would be happy to host it.</div><div><br></div><div>I would be much more comfortable maintaining a standardized definition of a "freestanding implementation", and I would support your push to fix the C++17 definition of freestanding.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><p class="MsoNormal"><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">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.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">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.</p></div></div></blockquote><div><br></div><div>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).</div><div><br></div><div>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.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><span class="">
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="border:none;padding:0in">> I think it would be much better to get as much of libc++ compiling as possible, even if it depends on restricted<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> features, and then finding another mechanism to restrict the features end-users are allowed to use (Such as clang-tidy).<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> This would eliminate the need to restructure headers or spam out internal #ifdef guards.</p></div></span></div></div></blockquote><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><span class=""><div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt"><p class="MsoNormal" style="border:none;padding:0in"><u></u><u></u></p>
</div>
</span><p class="MsoNormal">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?</p></div></div></blockquote><div><br></div><div>What kind of static asserts? Can you provide an example? </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><span class="">
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="border:none;padding:0in">>> * I'll also need to figure out how to not drag along unwanted header dependencies.<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in"><u></u> <u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> I don't see how libc++ could upstream changes since it requires every header<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> it currently includes (modulo bugs).<u></u><u></u></p>
</div>
</span><p class="MsoNormal">The straightforward (and labor intensive) way is with #ifdef _LIBCPP_HAS_NO_ALLOC<u></u><u></u></p><span class="">
<p class="MsoNormal"><u></u> </p></span></div></div></blockquote><div><br></div><div>_LIBCPP_HAS_NO_ALLOC is exactly the invasive change I wanted to avoid. First <new> is currently a freestanding header,</div><div>and I think it should stay that way. Second I want to avoid the maintenance cost of such a restrictive</div><div>configuration. This macro would have to guard the the vast majority of the library, unlike</div><div>_LIBCPP_HAS_EXCEPTIONS and _LIBCPP_NO_RTTI which have a much smaller and more manageable scope.</div><div><br></div><div>If the end goal is simply to diagnose when end users use features that dynamically allocate I suspect there</div><div>are less invasive ways to do it. First there are two important things to note:</div><div><br></div><div>(1) Libc++ has very few naked new/delete calls. Almost all dynamic allocations go through std::allocator.</div><div>(2) std::allocator is typically used in dependent contexts (templates). </div><div><br></div><div>Instead of #ifdef'ing out std::allocator and everything that uses it, we could make instantiating std::allocator::allocate</div><div>produce a diagnostic. This would make the changes needed within libc++ significantly smaller while still</div><div>producing reasonable diagnostics when users attempt to use those types.</div><div><br></div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><span class="">
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="border:none;padding:0in">> Using hard-coded kernel paths is not a change I see being upstream-able. However<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> we might be able to convince MSVC to implement #include_next if we can provide<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> strong enough rational for why we need it.<u></u><u></u></p>
</div>
</span><p class="MsoNormal">These wouldn't be hard coded paths.  The code would look something like...<u></u><u></u></p>
<p class="MsoNormal">#if __LIBCPP_HAS_INCLUDE_NEXT<u></u><u></u></p>
<p class="MsoNormal">#include_next <limits.h><u></u><u></u></p>
<p class="MsoNormal">#else<u></u><u></u></p>
<p class="MsoNormal">#include __LIBCPP_HACK_INCLUDE_NEXT(<wbr>limits.h)<u></u><u></u></p>
<p class="MsoNormal">#endif<u></u><u></u></p>
<p class="MsoNormal">__config would have the definition of __LIBCPP_HACK_INCLUDE_NEXT, and
<u></u><u></u></p>
<p class="MsoNormal"><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).</p></div></div></blockquote><div><br></div><div>That sounds like a fairly reasonable solution. Although aren't macro expansions inside #include directives UB?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><p class="MsoNormal"><u></u><u></u></p><span class="">
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="border:none;padding:0in">> I'm violently against working around MSVC template bugs. Every time I've seen<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> it done it makes the implementation worse.<u></u><u></u></p>
</div>
</span><p class="MsoNormal">That's fair.  I will say that not _all_ of the workarounds make worse code,<u></u><u></u></p>
<p class="MsoNormal">but quite a few do.  This may end up being what forces me to MSVC 2017.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">One example of a workaround that I don't think made things worse...<u></u><u></u></p>
<p class="MsoNormal">struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail {<u></u><u></u></p>
<p class="MsoNormal">     template <class ...><u></u><u></u></p>
<p class="MsoNormal">-    static constexpr bool __enable_default() { return false; }<u></u><u></u></p>
<p class="MsoNormal">+    static constexpr bool __enable_default = false;</p></div></div></blockquote><div><br></div><div>Your example uses C++14 variable templates, which I don't think you intended because MSVC 2015 doesn't support</div><div>them either.</div><div><br></div><div>Ironically that's a perfect example of a change that would make things drasticly worse.<br></div><div>First the suggested fix cannot be applied because variable templates are C++14 features.</div><div>Second we couldn't use a non-template in this case because it's important that the result is</div><div>type dependent in the non-fail cases to prevent eager SFINAE evaluation.</div><div><br></div><div>The <tuple> SFINAE is very complicated and it's full of subtle but important details.</div><div>It can barely manage it with a fully conforming C++11 compiler.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><p class="MsoNormal"><u></u><u></u></p><span class="">
<p class="MsoNormal"><u></u><u></u></p>
<div style="border:none;border-left:solid windowtext 1.0pt;padding:0in 0in 0in 4.0pt">
<p class="MsoNormal" style="border:none;padding:0in">> Another point is that libc++ doesn't have an <atomic> implementation for MSVC<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> so adding MSVC support would required adding one.<u></u><u></u></p>
</div>
</span><p class="MsoNormal">Yep, I've got one implemented (and untested).  This is the biggest reason why<u></u><u></u></p>
<p class="MsoNormal">I excluded ARM support explicitly.</p></div></div></blockquote><div><br></div><div>Nice!</div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="#954F72"><div class="m_-5679318130122211826WordSection1"><div><div class="h5">
</div></div></div>
</div>

</blockquote></div><br></div></div>