Bug 3796 – Result of .stringof is affected by unrelated function declarations
Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
Other
OS
Windows
Creation time
2010-02-12T05:05:00Z
Last change time
2014-02-24T15:33:43Z
Assigned to
nobody
Creator
clugdbug
Comments
Comment #0 by clugdbug — 2010-02-12T05:05:31Z
All 3 pragmas should give the same result (except for uint/short/ushort).
But declaring function pointers (dg2 and dg3 below) causes the output to change.
Related to bug 1424.
===TEST CASE===
void foo(ref uint i) { }
void foo2(ref short i) { }
void foo3(ref ushort i) { }
static if (is(typeof(foo2) P2 == function))
alias P2 FooParams2;
static if (is(typeof(foo3) P3 == function))
alias P3 FooParams3;
void function(ref FooParams2) dg2;
void function(ref FooParams3[0]) dg3;
pragma(msg, typeof(&foo).stringof);
pragma(msg, typeof(&foo2).stringof);
pragma(msg, typeof(&foo3).stringof);
---OUTPUT---
void function(ref uint i)
void function(ref (ref short))
void function(ref ushort)
---OUTPUT if comment the lines creating dg2 and dg3---
void function(ref uint i)
void function(ref short i)
void function(ref ushort i)
Comment #1 by bugzilla — 2010-02-13T00:33:13Z
Types are stored in an associative array indexed by the mangled string for the type. The problem is that there are different ways to have a function type that produces the same mangling - i.e. the arguments can be tuples or not tuples.
The problem shows up when trying to take the pointer to a function type, and different functions have become represented by one of the original function mangled types.
Comment #2 by bugzilla — 2010-02-13T00:36:21Z
The problem could be fixed by having .stringof demangle the deco, rather than pretty-printing the type it came from. Unfortunately, there isn't a demangler in the compiler at the moment.
Comment #3 by r.sagitario — 2010-02-13T01:27:59Z
Here's a test case closely related that's been bugging me:
--- test.d
void foo_a(int a) {}
void foo_b(int b) {}
pragma(msg,"foo_a: " ~ typeof(&foo_a).stringof);
pragma(msg,"foo_b: " ~ typeof(&foo_b).stringof);
--- dmd -c test.d
foo_a: void function(int a)
foo_b: void function(int a)
I'd suggest removing the argument identifiers from the stringof (as the suggestion of converting back the deco would do); it's not part of the type.
Unfortunately this disables some ctfe magic accessing function arguments (but that also badly fails sometimes due to this problem). So some fail-safe way to get the argument identifiers for ctfe would be nice...
Comment #4 by bugzilla — 2010-02-13T14:47:25Z
Yes, I think it's pretty clear going the demangler route is better. I agree there should be some other means to get the parameter identifiers.
Comment #5 by code — 2013-01-16T21:39:05Z
*** This issue has been marked as a duplicate of issue 6902 ***
Comment #6 by andrej.mitrovich — 2013-02-08T11:25:51Z
(In reply to comment #2)
> The problem could be fixed by having .stringof demangle the deco, rather than
> pretty-printing the type it came from. Unfortunately, there isn't a demangler
> in the compiler at the moment.
This is the code used right now:
/* Bugzilla 3796: this should demangle e->type->deco rather than
* pretty-printing the type.
*/
char *s = e->toChars();
But why not call e->type->toChars()? This would partially fix Issue 9460.