[cfe-dev] bug with USRs and fixed-length arrays?

Iestyn Bleasdale-Shepherd iestyn at valvesoftware.com
Fri Nov 2 12:37:16 PDT 2012

Ah, you are right! There is an extra ingredient in our usage cases: templates*

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).

However, here are the USRs that I get in a templatized example case:

template <class buffer> void mystrlwr( buffer &dst );                     // c:@FT@>1#Tmystrlwr#&t0.0#
template <> void mystrlwr<char[16]>( char (&dst)[16] );                               // c:@F at mystrlwr<# >#&S0_#
template <> void mystrlwr<char[32]>( char (&dst)[32] );                               // c:@F at mystrlwr<# >#&S0_#
template <> void mystrlwr<char[64]>( char (&dst)[64] );                               // c:@F at mystrlwr<# >#&S0_#

Here, the type buffer type gets reduced to " " as a template parameter and "S0_" as a function parameter.

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.


*[ 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! ;) ]

From: James Dennett [mailto:james.dennett at gmail.com]
Sent: Friday, November 02, 2012 12:12 PM
To: Iestyn Bleasdale-Shepherd
Cc: Dmitri Gribenko; cfe-dev at cs.uiuc.edu
Subject: Re: [cfe-dev] bug with USRs and fixed-length arrays?

On Fri, Nov 2, 2012 at 11:49 AM, Iestyn Bleasdale-Shepherd <iestyn at valvesoftware.com<mailto:iestyn at valvesoftware.com>> wrote:
Hi Dmitri - thanks for the response!

The line you quote ends with "...where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation."

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.

According to the rules of C++, the two declarations
  void Func(char array[32]);
  void Func(char array[16]);
declare the same function, which has one parameter of type char*.  They declare the same function as
  void Func(char *array);

It is an error to define both of them -- the following should generate a diagnostic from any conforming C++ compiler:
  void Func(char array[32]) {}
  void Func(char array[16]) {}

And it does so with Clang:

/tmp/redecl.cc:2:6: error: redefinition of 'Func'
void Func(char array[16]) {}
/tmp/redecl.cc:1:6: note: previous definition is here
void Func(char array[32]) {}
1 error generated.

(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.)

Am I missing something here? We use these kinds of overloads in our code, in cases which depend on their resolving to *different* functions.

That's not possible in C++.  Maybe you can show your actual code?

-- James

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121102/251774c5/attachment.html>

More information about the cfe-dev mailing list