<div dir="ltr">Ping.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Nov 5, 2015 at 6:32 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Ping.</div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 29, 2015 at 5:21 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<div><br></div><div>The attached patch undoes the revert of r249929, and adds an extension to allow <string.h> (and <wchar.h>) to work properly even in environments such as iOS where the underlying libc does not provide C++'s const-correct overloads of strchr and friends.</div><div><br></div><div>This works as follows:</div><div><br></div><div> * The macro _LIBCPP_PREFERRED_OVERLOAD is, where possible, defined by <__config> to an attribute that provides the following semantics:</div><div>   - A function declaration with the attribute declares a different function from a function declaration without the attribute.</div><div>   - Overload resolution prefers a function with the attribute over a function without.</div><div> * For each of the functions that has a "broken" signature in C, if we don't believe that the C library provided the C++ signatures, and we have a _LIBCPP_PREFERRED_OVERLOAD, then we add the C++ declarations and mark them as preferred over the C overloads.</div><div> * The overloads provided in namespace std always exactly match those in ::.</div><div><br></div><div><br></div><div>This results in the following changes in cases where the underlying libc provides the C signature not the C++ one, compared to the status quo:</div><div><br></div><div><br></div><div><string.h>:</div><div><br></div><div><div>      char *strchr(const char*, int) // #1</div><div>      char *strchr(char*, int) // #2</div></div><div><div>      const char *strchr(const char*, int) // #3</div></div><div><br></div><div>We used to provide #1 and #2 in namespace std (in <cstring>) and only #1 in global namespace (in <string.h>).<br></div><div><br></div><div>For a very old clang or non-clang compiler, we now have only #1 in both places (note that #2 is essentially useless). This is unlikely to be a visible change in real code, but it's slightly broken either way and we can't fix it.</div><div><br></div><div>For newer clang (3.6 onwards?), we now have correct signatures (#2 and #3) in :: and std (depending on header). Taking address of strchr requires ~trunk clang (but it didn't work before either, so this is not really a regression).</div><div><br></div><div><br></div><div><wchar.h>:</div><div><br></div><div>      wchar_t *wcschr(const wchar_t *, wchar_t) // #1</div><div>      const wchar_t *wcschr(const wchar_t *, wchar_t) // #2</div><div>      wchar_t *wcschr(wchar_t *, wchar_t) // #3</div><div><br></div><div><div>We used to provide #1 in global namespace, and #2 and #3 in namespace std. This broke code that uses 'using namespace std;'.</div></div><div><br></div><div>For a very old clang or non-clang compiler, we now have #1 in global namespace and namespace std. This fixes the ambiguity errors, but decreases const-correctness in this case. On the whole, this seems like an improvement to me.</div><div><br></div><div>For newer clang, we now have correct signatures (#2 and #3) in :: and std (depending on header). As above, taking address doesn't work unless you're using very recent Clang (this is not a regression in ::, but is a regression in namespace std).</div><div><br></div><div><br></div><div>To summarize, we previously had ad-hoc, inconsistent, slightly broken rules for <cstring> and <cwchar>, and with this patch we fix the overload set to give the exact C++ semantics where possible (for all recent versions of Clang), and otherwise leave the C signatures alone.</div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>