Bug 13247 – switch doesn't work with pointers to functions. Also casting pointers to functions to integers doesn't work during compilation.
Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Mac OS X
Creation time
2014-08-03T20:00:00Z
Last change time
2014-08-04T18:45:12Z
Assigned to
nobody
Creator
andrei
Comments
Comment #0 by andrei — 2014-08-03T20:00:58Z
Consider:
void fun(T)() {}
enum A
{
_1 = &fun!int,
_2 = &fun!string,
_3 = &fun!double,
}
void main(string[] args) {
A a = A._1;
final switch (a)
{
case A._1: writeln("eh"); break;
case A._2: writeln("meh"); break;
case A._3: writeln("neh"); break;
}
}
The enum works but the switch doesn't. Trying to force to integrals:
void fun(T)() {}
enum A
{
_1 = cast(size_t) &fun!int,
_2 = cast(size_t) &fun!string,
_3 = cast(size_t) &fun!double,
}
void main(string[] args) {
A a = A._1;
final switch (a)
{
case A._1: writeln("eh"); break;
case A._2: writeln("meh"); break;
case A._3: writeln("neh"); break;
}
}
Now the enum doesn't compile. Would be great if at least one of these worked.
Comment #1 by dfj1esp02 — 2014-08-04T04:38:15Z
How can it work? Function addresses are not compile-time constants. Sometimes they are runtime values.
Comment #2 by yebblies — 2014-08-04T09:19:11Z
While you can do some things with a function pointer at compile time, you _cannot_ convert it to an integer.
I'm not sure why you would expect switch to work on function pointers.
Comment #3 by andrei — 2014-08-04T18:02:46Z
(In reply to yebblies from comment #2)
> While you can do some things with a function pointer at compile time, you
> _cannot_ convert it to an integer.
Can you elaborate? Couldn't the linker just fix up the address as it does for calls?
> I'm not sure why you would expect switch to work on function pointers.
In std.variant, sometimes it's better to just switch on the tag (which is a pointer to function) instead of making an indirect call through it.
Comment #4 by yebblies — 2014-08-04T18:42:21Z
(In reply to Andrei Alexandrescu from comment #3)
> (In reply to yebblies from comment #2)
> > While you can do some things with a function pointer at compile time, you
> > _cannot_ convert it to an integer.
>
> Can you elaborate? Couldn't the linker just fix up the address as it does
> for calls?
I think for both integer enums and final switch, the integral value needs to be known at compile-time. Knowing at link-time isn't enough. How else do you ensure cases are distinct?
This is probably _possible_ to implement, but you won't get any nice jump-table optimizations out of the switch anyway.
Actually, with ASLR function addresses may not be known until load time. I'm not sure exactly how this would work out in PIC, but I doubt it's pretty.
>
> > I'm not sure why you would expect switch to work on function pointers.
>
> In std.variant, sometimes it's better to just switch on the tag (which is a
> pointer to function) instead of making an indirect call through it.
I think it's quite reasonable for an advanced linker or compiler to merge functions with the same body. This would mean function pointers are not necessarily distinct. I think it can break the other way too - the same function can have different addresses, if it is compiled into two different modules (ie dlls/shared objects).