<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;}
@font-face
        {font-family:"Book Antiqua";
        panose-1:2 4 6 2 5 3 5 3 3 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        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;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Book Antiqua",serif;
        color:#943634;
        font-weight:normal;
        font-style:normal;
        text-decoration:none none;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
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-IE link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>The discussion on the Standards reflector at the time that this text was ratified was about how the C names were introduced into the global namespace, otherwise all that needed to be said was:<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><math.h></span><span style='font-family:"Book Antiqua",serif;color:black;mso-fareast-language:EN-US'> is simply equivalent to:<o:p></o:p></span></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-family:"Book Antiqua",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>#include <cmath><o:p></o:p></span></p><p class=MsoNormal style='margin-left:72.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>using namespace std;<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>I understand your perspective on what is now section “</span><span style='font-family:"Book Antiqua",serif;color:black;mso-fareast-language:EN-US'>D.5 C standard library headers [depr.c.headers]</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>” in the WP, but this also has to be interpreted in the context of ISO’s fundamental charter which is “to standardise existing practice”.  I do not think anyone could argue with what is meant by existing practice concerning the inclusion of C headers in the context of a C++ program.  It looks to me now like the wording here introduced an unintended ambiguity in the language of the C++ Standard.<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>I do try to educate people to do C++ the C++ way, and include ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><cXXXX></span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ and then ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>using namespace std;</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ instead of ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><XXXX.h></span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’, and it bugs me when they don’t; but in practice they ignore such advice.  In fact, the majority of programs that are ported from C to C++ start out life by simply being renamed from “</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>.c</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>” to “</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>.cpp</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>”.  I would say that a good 90% of programmers using C++ for embedded systems are actually C programmers trying to “move up” and to take advantage of the extraordinary compile-time optimisations possible when templates are used (I still think that this is awesome versus C).<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>fabs</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ and ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>__fp16</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ was simple the observable failure that drew my attention to the issues but another example is the simpler ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>abs</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ from ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><stdlib.h></span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’.  In this case (in C) there is just one function:<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>int abs(int);<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>so code such as:<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>#include <stdint.h><o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>int a;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>float b;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>double c;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>__fp16 d;  // I’ve left FP16 in just to show that it is not really different<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>abs(a); // implicitly abs(a)<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>abs(b); // implicitly abs((int)b)<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>abs(c); // implicitly abs((int)c)<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>abs(d); // implicitly abs((int)d)<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>previously chose ONLY ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>int ::abs(int)</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’, but by introducing overloads to the C functions at global scope, the semantics and behaviour of ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>abs(b)</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ and ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>abs(c)</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ changes, and because ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>__fp16</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ is not a recognised type, it becomes ambiguous.  At least I see from the error message that the ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>__fp16</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ case is now broken, but the ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>float</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ and ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>double</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ variants silently do something very different by calling different functions whose semantic implementation of ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>abs</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ I can only trust is true.  I mentioned ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>__fp16</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ earlier because that was the unhandled data type that made an otherwise silent and hidden semantic change visible to me.  We also found problems with ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>putc</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ by the way, where it silently went from being a MACRO to an externally linked function resulting in unresolved link errors.  This was slightly different, but the underlying pattern change was the same.<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>The same ambiguity will arise whenever a class with a UDC to one of the overloaded types is involved, it is not just the tacitly implemented ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>__fp16</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ data type.<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>This change is not existing practice, and I am surprised it was not vetoed, I would have certainly would have advised vetoing this if I was still active in our national Standardisation panel.<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>It also breaks previously previously “compliant” C++, for example:<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>#include <stdlib.h><o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>struct Foo {<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>  operator double () const;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>  operator int () const;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>};<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>Foo aFoo;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>int x = abs(aFoo);<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>I’m not advocating such code, but without your interpretation of this clause, the above was valid, compliant and unambiguous.  It chose ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>int ::abs(int)</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ and used ‘</span><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>Foo::operator int()const</span><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>’ to satisfy it.  But with your interpretation it is now a compile-time error - ambiguous selection.<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>Even worse are existing compliant C++ programs such as:<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>#include <stdlib.h><o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>struct Bar {<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>  operator double () const;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>};<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>Bar aBar;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>int x = abs(aBar);<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>The effective code subtly changes silently from:<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>int x = abs((int)aBar.operator double());  // choosing ‘int ::abs(int)’<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>to:<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>int x = (int)abs(aBar.operator double());  // choosing ‘double ::abs(double)’<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>My interpretation of the clause in [depr.c.headers] is not that it is equivalent to:<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>using std::abs;<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>which brings in the whole overload set, but rather something like:<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-family:"Courier New",serif;color:black;mso-fareast-language:EN-US'>using std::abs(int); // sic! - but selects an element of the overload set<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>these have very different meanings and intent.  The inclusion of a Standard header does not mean that textual inclusion or syntactic equivalence is required, it only requires that the Standard names become available to the program with their intended meaning.  And I believe that this is why the Standard does not specify “how” the names get into the global namespace - textual inclusion is just a common way of doing implementing.<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>My original message was not criticise the new implementation, but to “critique” it and highlight that it has changed the expected semantics and hence the “existing practice” tenet of Standard C++.  If it wasn’t for the fact that we are looking at v3.8 code freeze very soon, I would not have brought it up as an urgent issue.<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'>            MartinO<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><b><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri",sans-serif'>From:</span></b><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri",sans-serif'> Eric Fiselier [mailto:eric@efcs.ca] <br><b>Sent:</b> 23 January 2016 20:13<br><b>To:</b> Martin J. O'Riordan <Martin.ORiordan@movidius.com><br><b>Cc:</b> Richard Smith <richard@metafoo.co.uk>; Clang Dev <cfe-dev@lists.llvm.org>; Marshall Clow <mclow.lists@gmail.com><br><b>Subject:</b> Re: [cfe-dev] LibC++ v3.8 - Problems with ISO C wrapper headers<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal>Hi Martin,<o:p></o:p></p><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>If you disagree you'll need to cite (or change) the standard. IMO the standard is explicitly clear on this topic. <o:p></o:p></p><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>15.2 [library.c] says:<o:p></o:p></p></div><div><p class=MsoNormal>> The C ++ standard library also makes available the facilities of the C standard library, suitably adjusted to<o:p></o:p></p><div><p class=MsoNormal>> ensure static type safety.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>D.3 [depr.c.headers] says:<o:p></o:p></p></div><div><p class=MsoNormal>>1. every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard<o:p></o:p></p></div><div><p class=MsoNormal>> library namespace by the corresponding cname header is placed within the global namespace scope. It is<o:p></o:p></p></div><div><p class=MsoNormal>> unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace<o:p></o:p></p></div><div><p class=MsoNormal>> std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>/Eric<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div></div></div></div><div><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal>On Sat, Jan 23, 2016 at 12:50 PM, Martin J. O'Riordan via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<o:p></o:p></p><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><p class=MsoNormal>I disagree.  I'm not new to C++ either, I built my first C++ compiler in 1986 and have been involved in C++ standardisation for a very long time, and the recent changes are wrong.<br><br>Including "math.h" should NOT introduce overloaded versions of 'fabs' or other functions at global scope.  It may only introduce the overloaded functions within "namespace std".  The recent changes overload these functions at global scope.  That is a bug.<br><br>My tests are running now, and when they are complete I will propose the patch, but I can assure you that overloading global symbols from the C headers is not compliant with C++.<br><br>        MartinO<o:p></o:p></p><div><div><p class=MsoNormal><br>-----Original Message-----<br>From: <a href="mailto:metafoo@gmail.com">metafoo@gmail.com</a> [mailto:<a href="mailto:metafoo@gmail.com">metafoo@gmail.com</a>] On Behalf Of Richard Smith<br>Sent: 23 January 2016 16:58<br>To: <a href="mailto:Martin.ORiordan@movidius.com">Martin.ORiordan@movidius.com</a><br>Cc: Clang Dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>><br>Subject: Re: [cfe-dev] LibC++ v3.8 - Problems with ISO C wrapper headers<br><br>Hi Martin,<br><br>On 1/23/16, Martin J. O'Riordan via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br>> While getting our implementation of the compiler ready for v3.8 we<br>> came across a significant problem in the new implementation of<br>> LibC++'s handling of the ISO C Standard headers that needs to be fixed<br>> before the v3.8 release.<br><br>You're mistaken about a lot of the things you say below, but I agree that your example code ought to work, assuming that libc++ intends to support __fp16 (but I don't think it currently does). See the bottom of my mail for a suggestion of how to move forward with this.<br><br>> We discovered the problem when running some tests that were derived<br>> from real-world code.  The initial example involved a C++ program<br>> including '<math.h>' and using 'fabs' but the issue applies equally to<br>> the other headers, for example:<br>><br>> #include <math.h><br>><br>> ...<br>><br>> __fp16 y;  // We use FP16 a lot<br>><br>> fabs(y);   // really -> fabs((double)y);<br>><br>> In C there is only one 'fabs' with the signature:<br>><br>> double fabs(double)<br><br>That's largely irrelevant. In C++, <math.h> is a C++ standard library header, whose contents are specified by C++'s [c.math] and [depr.c.headers]. These say that <math.h> provides the same set of overloads in the global namespace that <cmath> provides in namespace std. libc++ has recently changed to implement this rule (that has<br>*always* been part of the C++ standard). Thus your suggested approach to fixing this is not appropriate.<br><br>> With the new implementation of the headers for LibC++, there is now a<br>> file named 'c++/math.h' that includes the C version and then<br>> supplements it for<br>> C++.  When I use this, the above use of 'fabs' above results in an<o:p></o:p></p></div></div><p class=MsoNormal>> C++overload<o:p></o:p></p><div><div><p class=MsoNormal>> ambiguity error.<br>><br>> It's easy to say "It's C++, use '<cmath>'",<br><br>That wouldn't help. In namespace std, libc++ has always provided overloads resulting in the ambiguity you're now seeing (and FWIW, this is the overload set required by the C++ standard).<br><br>[...]<br>> and has odd incongruities such as:<br>><br>> #include <math.h><br>><br>> float       (*pf)(float)        = std::fabs; // Okay, we have this<br>> long double (*pld)(long double) = std::fabs; // Okay, we have this too<br>> double      (*pd)(double)       = std::fabs; // Oops, no such function<br><br>That seems a consequence of your (incorrect) patch. libc++'s current <math.h> doesn't provide any of these in namespace std, consistent with the requirements of the C++ standard. The intent is that no set of #includes gives you a partial overload set for any of these functions (except cases like 'abs', where C++ specifies that the overload set is split across multiple headers).<br><br><br>The real issue is that libc++ doesn't support __fp16 (you should be able to observe this with both past versions of libc++ and with trunk if you change your testcase to use <cmath> and std::fabs). The right way to fix this would be to add __fp16 overloads to <math.h> (in the cases where the underlying compiler and language mode provide such a<br>type) and ensure its __promote does the right thing for __fp16. It's up to the libc++ maintainers whether they consider this to be a regression and whether they'd accept a patch for it in the 3.8 release.<br><br>But it's not a bug that libc++'s <math.h> now follows the C++ standard when compiling in C++ mode.<br>--<br>Richard<br><br>_______________________________________________<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" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><o:p></o:p></p></div></div></blockquote></div><p class=MsoNormal><o:p> </o:p></p></div></div></body></html>