<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:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" 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=us-ascii">
<meta name="Generator" content="Microsoft Word 12 (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:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 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;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;}
@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">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Ah, you are right! There is an extra ingredient in our usage cases: templates*<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">For example, we use templates to implement ‘safe’ string functions which use the type of the destination buffer (a fixed-length character array) as the template
 parameter, rather than passing in the array size as a function parameter (which is error-prone – array size sometimes being confused with array length, for multi-byte characters).<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">However, here are the USRs that I get in a templatized example case:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-indent:.5in"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">template <class buffer> void mystrlwr( buffer &dst );                     // c:@FT@>1#Tmystrlwr#&t0.0#<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent:.5in"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">template <> void mystrlwr<char[16]>( char (&dst)[16] );                               // c:@F@mystrlwr<# >#&S0_#<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent:.5in"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">template <> void mystrlwr<char[32]>( char (&dst)[32] );                               // c:@F@mystrlwr<# >#&S0_#<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent:.5in"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">template <> void mystrlwr<char[64]>( char (&dst)[64] );                               // c:@F@mystrlwr<# >#&S0_#<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Here, the type buffer type gets reduced to “ “ as a template parameter and “S0_” as a function parameter.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">The function parameter may be valid (though according to the quoted specification, shouldn’t it be “*C”?), but the template parameter definitely seems wrong
 – those are three different functions, all with the same USR.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">iestyn<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">*[ I suspect my use of the Microsoft compiler was clouding the results of my simplified test cases. As you are all no doubt shocked to hear! ;) ]<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> James Dennett [mailto:james.dennett@gmail.com]
<br>
<b>Sent:</b> Friday, November 02, 2012 12:12 PM<br>
<b>To:</b> Iestyn Bleasdale-Shepherd<br>
<b>Cc:</b> Dmitri Gribenko; cfe-dev@cs.uiuc.edu<br>
<b>Subject:</b> Re: [cfe-dev] bug with USRs and fixed-length arrays?<o:p></o:p></span></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Fri, Nov 2, 2012 at 11:49 AM, Iestyn Bleasdale-Shepherd <<a href="mailto:iestyn@valvesoftware.com" target="_blank">iestyn@valvesoftware.com</a>> wrote:<o:p></o:p></p>
<p class="MsoNormal" style="margin-bottom:12.0pt">Hi Dmitri - thanks for the response!<br>
<br>
The line you quote ends with "...where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation."<br>
<br>
This qualification allows disambiguation between my two example functions - as it must, since they may have completely different implementations and may be passed as different function pointers.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">According to the rules of C++, the two declarations<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  void Func(char array[32]);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">and<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  void Func(char array[16]);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">declare the same function, which has one parameter of type char*.  They declare the same function as<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  void Func(char *array);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">It is an error to define both of them -- the following should generate a diagnostic from any conforming C++ compiler:<o:p></o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">  void Func(char array[32]) {}<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  void Func(char array[16]) {}<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">And it does so with Clang:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">/tmp/redecl.cc:2:6: error: redefinition of 'Func'<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">void Func(char array[16]) {}<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">     ^<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">/tmp/redecl.cc:1:6: note: previous definition is here<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">void Func(char array[32]) {}<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">     ^<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">1 error generated.<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">(It's true that arrays are not pointers, and pointers are not arrays, but in the special case of function declarations there is no way to pass an array by value, and the only way to constrain the size of a passed array is to pass a pointer
 or reference to a particular size of array.)<o:p></o:p></p>
</div>
<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">
<p class="MsoNormal">Am I missing something here? We use these kinds of overloads in our code, in cases which depend on their resolving to *different* functions.<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">That's not possible in C++.  Maybe you can show your actual code?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">-- James<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>