<div dir="ltr"><div>On Tue, Mar 28, 2017 at 11:28 AM, Ben Craig via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br></div><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_5554497396065222699WordSection1"><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">>> There are often ways to safely use STL containers w/o exceptions (Especially when custom allocators are provided).
<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> Yes, but those ways generally involve going to terminate() on OOM. That's not OK in a driver.<u></u><u></u></p>
</div>
</span><p class="MsoNormal">There is another way, but it isn't conforming, it's easy to get wrong in the library, and it's easy to get wrong for users. It's basically the alternative that my company has used with STL Port.<u></u><u></u></p>
<p class="MsoNormal">You take an allocator (maybe even the default allocator), and you return nullptr on failure. You also add a bool member (possibly static) that indicates whether the allocator has failed. Then you check that bool anytime you use an STL
container in a way that could fail.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">This approach sort-of works with std::vector, especially if you develop reserve() paranoia. It sort-of works with std::string if you ignore all the temporaries that std::string operations tend to generate. It doesn't work very well at
all for the node based containers, because they tend to dereference the node immediately after allocating it.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">It's not really an approach I want to endorse. My company has some home-rolled, STL inspired containers that use error codes, and sometimes even require "T" to have specific constructors that take those error codes by reference. That
approach is still error-prone, but less error-prone than using an STL container in a way that it wasn't intended.<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">> Before responding in depth I need to ask this question: Why not use Clang/C2 or simply Clang+LLVM?<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> I'm assuming they don't support targeting the kernel?<u></u><u></u></p>
</div>
</span><p class="MsoNormal">I haven't even attempted to use Clang targeting the Windows kernel. I did attempt to point Clang's static analyzer at a kernel component once, and I got some decent results... plus a lot of compiler errors that I hadn't worked through.
I've done nothing with Clang/C2 so far.<u></u><u></u></p>
<p class="MsoNormal">There are some strange MSVC flags required to build for the kernel. I didn't see any web documentation for making stdcall the default calling convention,</p></div></div></blockquote><div><br></div><div>clang-cl implements /Gz as far as I can tell.</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_5554497396065222699WordSection1"><p class="MsoNormal"> or the dreaded /Zc:wchar_t-, which turns wchar_t into an unsigned short.</p></div></div></blockquote><div><br></div><div>This isn't implemented, but probably isn't too hard to add, if you want to give it a shot.</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_5554497396065222699WordSection1"><p class="MsoNormal"><u></u><u></u></p>
<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.<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.<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">> For example What if the Windows Kernel C library is incomplete, or significantly different from existing implementations [...]<u></u><u></u></p>
</div>
<p class="MsoNormal">Depends on what it is. If it is something niche, I will likely want to just not support that particular use. For example, floating point use "works" in x86 kernel mode, with a pile of caveats and extra code. If supporting that becomes
annoying from my side, I'll likely just drop float.h and cfloat support. Basically, if the kernel C library doesn't have support for it, I probably shouldn't be doing it...<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">... unless it's using the STL in the kernel. Then, I'm totally in the right :)<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">> My main concern with (4) is the limited feature set that has been proposed. Specifically<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> how it limits the libc++ internals to the same feature set and the changes that would be<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> needed to support and maintain it.<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">> 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?<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.<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">> <u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> Second, the changes required to either guard restricted features using #ifdef or remove restricted features<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> by re-structuring the headers would be vast and would require constant maintenance. Frankly I don't<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> see how libc++ or its existing users could benefit from upstreaming these changes (For example adding<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> #ifdef guards for every usage of `operator new`).<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</span><p class="MsoNormal">I hope to use this project as a way to provide implementation experience to revise the definition of a freestanding implementation. I think that C++11 got it wrong, and that the current definition isn't useful. I also believe that other
kernel, embedded, and bare-metal users would want the same feature set that I'm looking for. This feature set would have been useful to me on other projects that weren't targeting the Windows Kernel.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">So for the cost, I agree that it will require a substantial amount of work. Let's say that it's somewhere between _LIBCPP_HAS_NO_THREADS and _LIBCPP_NO_EXCEPTIONS amount of work. There is still benefit for other users though.<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 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.<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?<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 don't think partitioning <algorithm> into smaller headers would be beneficial<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> to existing libc++ users (If that's what you're suggesting).
<u></u><u></u></p>
</div>
</span><p class="MsoNormal">The three obvious options are 1) do nothing, 2) #ifdefs around the existing declarations and definitions, and 3) #ifdefs around #includes that pull in the supported feature set. I could also put static_asserts in select areas that I know
will cause trouble.<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'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> <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">> My only idea for handling this would be to write a script to rename main() to some<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> unique function name and creating a separate test-driver that calls the re-named main.<u></u><u></u></p>
</div>
</span><p class="MsoNormal">I had similar thoughts. Alternatively, I could just run execution tests overnight. I can call main just fine, I just can't call 5000 different functions each called main.<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 could envision a fix which replaces `<assert.h>` when compiling the tests, but that<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> would be a hack. Maybe the Windows Kernel C library provides a mechanism for replacing<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> the assert handler?<u></u><u></u></p>
</div>
</span><p class="MsoNormal">I think the best solution, long term, is to use an "expect" macro instead of an assert macro, similar to google test. I'm not sure that I want to take that on though. "assert" is used in more than 4000 tests. I'll have to look at this
more later.<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">> 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).<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;<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.<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 hope my response has been helpful, and it hasn't scared you away from using libc++.<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> These are my initial reactions and are in no way absolute. Please let me know if I can<u></u><u></u></p>
<p class="MsoNormal" style="border:none;padding:0in">> clarify anything or if I got anything wrong.<u></u><u></u></p>
</div>
</span><p class="MsoNormal">The response has been helpful and useful. No complaints here on the tone or style of your reply.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Thanks,<u></u><u></u></p>
<p class="MsoNormal">Ben Craig<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Billy O'Neal (VC LIBS) [mailto:<a href="mailto:bion@microsoft.com" target="_blank">bion@microsoft.com</a>]
<br>
<b>Sent:</b> Monday, March 27, 2017 6:42 PM<br>
<b>To:</b> Eric Fiselier <<a href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>>; Ben Craig <<a href="mailto:ben.craig@ni.com" target="_blank">ben.craig@ni.com</a>><br>
<b>Cc:</b> via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>; <a href="mailto:mclow.lists@gmail.com" target="_blank">mclow.lists@gmail.com</a>; Stephan T. Lavavej <<a href="mailto:stl@exchange.microsoft.com" target="_blank">stl@exchange.microsoft.com</a>>; Casey@Carter.net<br>
<b>Subject:</b> RE: [libc++] RFC: Add Windows kernel support and partial MSVC 2015 support<u></u><u></u></p>
</div>
</div><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">> There are often ways to safely use STL containers w/o exceptions (Especially when custom allocators are provided).<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Yes, but those ways generally involve going to terminate() on OOM. That's not OK in a driver.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From: </b><a href="mailto:eric@efcs.ca" target="_blank">Eric Fiselier</a><br>
<b>Sent: </b>Monday, March 27, 2017 4:37 PM<br>
<b>To: </b><a href="mailto:ben.craig@ni.com" target="_blank">Ben Craig</a><br>
<b>Cc: </b><a href="mailto:cfe-dev@lists.llvm.org" target="_blank">via cfe-dev</a>; <a href="mailto:mclow.lists@gmail.com" target="_blank">
mclow.lists@gmail.com</a>; <a href="mailto:bion@microsoft.com" target="_blank">Billy O'Neal (VC LIBS)</a>;
<a href="mailto:stl@exchange.microsoft.com" target="_blank">Stephan T. Lavavej</a>; <a href="mailto:Casey@carter.net" target="_blank">
Casey@Carter.net</a><br>
<b>Subject: </b>Re: [libc++] RFC: Add Windows kernel support and partial MSVC 2015 support<u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Sat, Mar 25, 2017 at 9:18 AM, Ben Craig <<a href="mailto:ben.craig@ni.com" target="_blank">ben.craig@ni.com</a>> wrote:<u></u><u></u></p>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal">Abstract:<br>
I would like to add Windows x86 and x64 kernel support to libc++. My initial<br>
compiler would be MSVC 2015 Update 3, though MSVC 2017 shouldn't be difficult to<br>
add after the fact.<br>
<br>
I would like to know if this is a port that the libc++ maintainers are willing<br>
to accept.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Before responding in depth I need to ask this question: Why not use Clang/C2 or simply Clang+LLVM?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">I'm assuming they don't support targeting the kernel?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<div>
<p class="MsoNormal">There seem to be three separate changes going on here, and each of the changes<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">will benefits and challenges. For that reason I think it's best to consider them<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">separately. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">(1) Porting to MSVC<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">(2) Supporting the Windows Kernel C library.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">(3) Implementation a Freestanding configuration of libc++<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">(4) Implementing the Kernel-space compatible configuration described in the original email.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">In general I'm happy to accept specific or niche libc++ changes as long as they<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">aren't detrimental to the overall libc++ quality and implementation complexity.<u></u><u></u></p>
</div>
<div>
<div>
<p class="MsoNormal">Changes to better support (1) or (3) would be beneficial to the larger libc++ audience and I would b<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">happy to upstream them. However I have large concerns regarding the changes required for (2) and (4)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">as I suspect they won't satisfy the above requirement.<u></u><u></u></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">For example What if the Windows Kernel C library is incomplete, or significantly different from<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">existing implementations, and supporting it requires re-implementing the missing parts within libc++?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">These portions would be virtually untestable outside of the Windows Kernel environment and would<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">quickly become unmaintained. Having such code in Libc++ could quickly become a detriment.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">My main concern with (4) is the limited feature set that has been proposed. Specifically<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">how it limits the libc++ internals to the same feature set and the changes that would be<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">needed to support and maintain it.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">First Libc++ cannot reasonably limit itself to the proposed language and library feature set since<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">it must be free to use "restricted" features within the implementation of non-restricted ones whenever<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">it is beneficial to the implementation. The burden of maintaining a working restricted feature set could<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">not fall on upstream maintainers.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Second, the changes required to either guard restricted features using #ifdef or remove restricted features<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">by re-structuring the headers would be vast and would require constant maintenance. Frankly I don't<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">see how libc++ or its existing users could benefit from upstreaming these changes (For example adding<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">#ifdef guards for every usage of `operator new`).<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">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>
</div>
<div>
<p class="MsoNormal">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>
</div>
<div>
<p class="MsoNormal">This would eliminate the need to restructure headers or spam out internal #ifdef guards.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal">This means that string, vector, and the non-array containers won't be ported.<br>
Any class or function that requires throwing exceptions to meet their standards<br>
required behavior will be omitted. That rules out a lot of classes that<br>
allocate memory.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">There are often ways to safely use STL containers w/o exceptions (Especially when<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">custom allocators are provided).<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal">Avoiding allocations allows us to sidestep one other large issue. In the<br>
kernel, not all memory is equal. There are several memory pools to choose from,<br>
but the two most common memory pools are the pageable pool and the non-pageable<br>
pool. There is no clear correct answer for which pool a global operator new<br>
should use, so we simply won't require an allocating new to be present for our<br>
implementation. Placement new shall remain though.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Containers don't use new/delete directly but instead go through the specified allocator,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">allowing containers to change the allocation behavior on a per-object basis. Not <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">supporting containers because of global operator new's behavior seems misguided.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal">My employer has significant experience using C++ in the kernel. We have been<br>
using a modified version of STLPort for quite some time and learned a lot about<br>
C++ library usage in the kernel, often the hard way. The big, obvious lesson<br>
is that a lot of the STL is either difficult, or impossible to work with when<br>
exceptions are off and std::terminate is undesired. There's nothing wrong with<br>
sorting in the kernel though. <u></u><u></u></p>
</blockquote>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal"><br>
Challenges:<br>
* Header partitioning.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Libc++ prefers larger monolithic headers over many well-partitioned headers. The idea is that hitting the filesystem<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">multiple times is slower than processing the single include file. Any proposed changes should keep this in mind.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal"> * I don't have an exact list of what functions and classes I will be<br>
keeping. I do know that some of the headers I want to bring along have<br>
parts that I won't be keeping. For instance, many of the algorithms<br>
allocate a temporary buffer in order to meet performance requirements.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I don't think partitioning <algorithm> into smaller headers would be beneficial<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">to existing libc++ users (If that's what you're suggesting). <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal"> * I'll also need to figure out how to not drag along unwanted header<br>
dependencies.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I don't see how libc++ could upstream changes since it requires every header<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">it currently includes (modulo bugs).<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal">* Testing.<br>
* Installing code so that it can be run in the kernel takes several seconds<br>
for each binary. <u></u><u></u></p>
</blockquote>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal"> * There is no facility in the Windows kernel for running a program starting<br>
at "main" in the context of the kernel.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I suspect this will be the largest hurdle to get the test-suite running. My only<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">idea for handling this would be to write a script to rename main() to some<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">unique function name and creating a separate test-driver that calls the re-named main.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">This could also allow us to combine multiple tests into a single executable, avoiding<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">the cost of installing every test manually.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal"> * The 32-bit Windows kernel requires a default calling convention of<br>
stdcall, but warns if "main" is not cdecl.<br>
* A common failure mode for libc++ tests is to crash or assert. That<br>
will "blue-screen" a machine.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I could envision a fix which replaces `<assert.h>` when compiling the tests, but that<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">would be a hack. Maybe the Windows Kernel C library provides a mechanism for replacing<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">the assert handler?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> .<u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal">* MSVC compiler feature set<br>
* No #include_next. I'll need to use computed include paths, like an<br>
STL using caveman.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Using hard-coded kernel paths is not a change I see being upstream-able. However<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">we might be able to convince MSVC to implement #include_next if we can provide<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">strong enough rational for why we need it.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal"> * Limited expression SFINAE. Some areas in the code are straightforward<br>
to fix, and others are not.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I'm violently against working around MSVC template bugs. Every time I've seen<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">it done it makes the implementation worse.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Another point is that libc++ doesn't have an <atomic> implementation for MSVC<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">so adding MSVC support would required adding one.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<p class="MsoNormal">* C-runtime<br>
* The Windows kernel has its own implementation of the C-runtime. I don't<br>
know all the details on it. I suspect (but don't know) that it is<br>
derived from Dinkumware, but I know that it is not the same C-runtime<br>
as used in user mode.<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I'm very curious to know the changes required to support the kernel C runtime.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Hopefully it's similar enough to other supported C libraries that very few changes<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">are needed.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I hope my response has been helpful, and it hasn't scared you away from using libc++.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">These are my initial reactions and are in no way absolute. Please let me know if I can<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">clarify anything or if I got anything wrong.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">/Eric<u></u><u></u></p>
</div>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
</div></div></div>
</div>
<br>______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div></div>