digitalmars.D.bugs - Name mangling is broken for integral template value arguments.
- Don Clugston (69/69) Feb 06 2006 The ABI page of the docs says the name mangling scheme is:
- Walter Bright (12/44) Feb 07 2006 It fails because frog!('A') passes 'A' of type 'char'. The specializatio...
- Walter Bright (4/14) Feb 07 2006 You're right, the docs are wrong, and I'll fix them.
- Don Clugston (28/46) Feb 08 2006 That's what happens for specialisations. But it doesn't happen for the
- Thomas Kuehne (14/60) Feb 11 2006 -----BEGIN PGP SIGNED MESSAGE-----
The ABI page of the docs says the name mangling scheme is: TemplateArg: T Type V Value S LName Value: n Number <----- this is wrong N Number e 20HexDigits c 20HexDigits 20HexDigits Width Number _ HexDigits So for example, given myTemplate!(37) it would be V37 but this is not what actually happens. Instead, the type comes after the V. It's "i" (integer) in this case, so we get Vi37 I think this is good; it's more general, and it allows the possibility of template value arguments being different for (say) char and int. I think the mangling rule should be: TemplateArg: T Type V ValueArg S LName ValueArg: Type Value and Value is Number for positive integral types, N Number for negative ints, hex digits for real/ireals, 2 x hex digits for creals, hex digits for strings. This is almost, but not quite, what happens now. I ran into this problem trying to make a toString!() metafunction; it would be nice to be able to distinguish toString!('A') --> returns "A" and toString!(65) --> returns "65". (However, you _can_ already make a seperate toString!(real) and toString!(creal), because they use different mangling rules). The problem is, the type used inside the mangled name seems to depend on how the template is SPECIALISED, but not on how it is DECLARED. So this example fails: ------- template frog(int F) { const int frog = 2; } template frog(int F:'A') { const int frog = 3; } static assert( frog!('A')==3); --------- It fails because the second template is not actually a specialisation of the first one! But, the following code works: ------ template frog(char F) { const int frog = 2; } template frog(char F:'A') { const int frog = 3; } static assert( frog!('A')==3); ------ Even more interesting is to use an enum as a template value argument, the name of the enum gets mangled into the template name. Which is really cool, it's a shame it doesn't work properly. Ideally, integral template arguments would use the same lookup rules as for integral function arguments, rather than the "everything's an int" rule from C++. Right now, we have a curious mix of the two, and you can generate some pretty interesting bugs.
Feb 06 2006
"Don Clugston" <dac nospam.com.au> wrote in message news:ds753m$2fve$1 digitaldaemon.com...The problem is, the type used inside the mangled name seems to depend on how the template is SPECIALISED, but not on how it is DECLARED. So this example fails: ------- template frog(int F) { const int frog = 2; } template frog(int F:'A') { const int frog = 3; } static assert( frog!('A')==3); --------- It fails because the second template is not actually a specialisation of the first one!It fails because frog!('A') passes 'A' of type 'char'. The specialization frog(int F:'A') means the parameter is of type 'int' with a value of '65', because the 'A' specialization is implicitly converted to 'int'. 'char' is not an 'int', so the specialization is not used.But, the following code works: ------ template frog(char F) { const int frog = 2; } template frog(char F:'A') { const int frog = 3; } static assert( frog!('A')==3); ------That works because 'A' is a char and matches the char type of the specialization.Ideally, integral template arguments would use the same lookup rules as for integral function arguments, rather than the "everything's an int" rule from C++. Right now, we have a curious mix of the two, and you can generate some pretty interesting bugs.Template matching in D follows the rule that specialization of values must match exactly. If there is more than one template of a given name, they aren't promoted to int. Also, for types, if there is more than one match the rule of "most specialized" is applied to disambiguate.
Feb 07 2006
"Don Clugston" <dac nospam.com.au> wrote in message news:ds753m$2fve$1 digitaldaemon.com...I think the mangling rule should be: TemplateArg: T Type V ValueArg S LName ValueArg: Type ValueYou're right, the docs are wrong, and I'll fix them.and Value is Number for positive integral types, N Number for negative ints, hex digits for real/ireals, 2 x hex digits for creals, hex digits for strings. This is almost, but not quite, what happens now.I thought it was what's happening now?
Feb 07 2006
Walter Bright wrote:"Don Clugston" <dac nospam.com.au> wrote in message news:ds753m$2fve$1 digitaldaemon.com...That's what happens for specialisations. But it doesn't happen for the non-specialised template. The non-specialised one always gets the type value int ("Vi"), regardless of what type was used in the declaration. Specialisations get the type from the declaration. The following code doesn't compile, because the first two templates are both template frog(int). But, if you comment out the first two, there's no conflict (you can overload specialisations, but not the template they are specialising!). ---------------------------- template frog(char F) { const int frog = 1; } template frog(int F) { const int frog = 2; } template frog(char F: 'A') { const int frog = 3; } template frog(int F: 65) { const int frog = 4; } static assert( frog!('A')==3); static assert( frog!(65)==4);I think the mangling rule should be: TemplateArg: T Type V ValueArg S LName ValueArg: Type ValueYou're right, the docs are wrong, and I'll fix them.and Value is Number for positive integral types, N Number for negative ints, hex digits for real/ireals, 2 x hex digits for creals, hex digits for strings. This is almost, but not quite, what happens now.I thought it was what's happening now?
Feb 08 2006
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Don Clugston schrieb am 2006-02-08:Walter Bright wrote:Added to DStress as http://dstress.kuehne.cn/run/t/template_27_A.d http://dstress.kuehne.cn/run/t/template_27_B.d http://dstress.kuehne.cn/run/t/template_27_C.d http://dstress.kuehne.cn/run/t/template_27_D.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFD7a503w+/yD4P9tIRAlZTAJ4oRW0uo5PHribSHpIYNxfLkvugIwCfcARh fc5wFa4QxiGLRex7FPij4ew= =J5Vq -----END PGP SIGNATURE-----"Don Clugston" <dac nospam.com.au> wrote in message news:ds753m$2fve$1 digitaldaemon.com...That's what happens for specialisations. But it doesn't happen for the non-specialised template. The non-specialised one always gets the type value int ("Vi"), regardless of what type was used in the declaration. Specialisations get the type from the declaration. The following code doesn't compile, because the first two templates are both template frog(int). But, if you comment out the first two, there's no conflict (you can overload specialisations, but not the template they are specialising!). ---------------------------- template frog(char F) { const int frog = 1; } template frog(int F) { const int frog = 2; } template frog(char F: 'A') { const int frog = 3; } template frog(int F: 65) { const int frog = 4; } static assert( frog!('A')==3); static assert( frog!(65)==4);I think the mangling rule should be: TemplateArg: T Type V ValueArg S LName ValueArg: Type ValueYou're right, the docs are wrong, and I'll fix them.and Value is Number for positive integral types, N Number for negative ints, hex digits for real/ireals, 2 x hex digits for creals, hex digits for strings. This is almost, but not quite, what happens now.I thought it was what's happening now?
Feb 11 2006