On 4 February 2018 at 05:01, Simon Marchi wrote: > On 2018-02-03 13:35, Manfred wrote: >> n4659 17.4 (Type equivalence) p1.3: >> >> Two template-ids refer to the same class, function, or variable if >> ... >> their corresponding non-type template arguments of integral or >> enumeration type have identical values >> ... >> >> It looks that for non-type template arguments the template type >> equivalence is based on argument /value/ not /type/ (and value), so >> IMHO gcc is correct where it considers foo<10u> and foo<10> to be the >> same type, i.e. "refer to the same class" >> >> FWIW, type_info reports the same class name for both templates, which >> appears to be correct as per the above. >> >> I would think someone from gcc might be more specific on why both >> templates print 4294967286, and what debug info is actually stored by >> -g in this case. > > I think that Roman's example clearly shows that they are not equivalent in > all cases. > > Building Roman's example with g++ 7.3 results in a single instantiated type. > You > can see that both "new foo<10>()" and "new foo<10u>()" end up calling the same > constructor. It seems like which type is instantiated depends on which > template > parameter (the signed or unsigned one) you use first. So with this: > > base * fi = new foo<10>(); > base * fu = new foo<10u>(); > > the output is -10 for both, and with > > base * fu = new foo<10u>(); > base * fi = new foo<10>(); > > the output is 4294967286 for both. But it's probably a bogus behavior. I > tested > with clangd, it instantiates two different types, so you get 4294967286 for > the > <10u> case and -10 for the <10> case. I also just built gcc from master, and > it > also instantiates two types, so it seems like that was fixed recently.
That was https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79092 FWIW