I have a container which provides access to data via a handle.
For book keeping I calculate some bitmasks.
Previously, when the handle type as well as the constants were
uint, everything compiled fine.
Today I added a template parameter to be able to specify the
handle type and I ran into this problem.
I've read the following information on the matter:
https://forum.dlang.org/thread/yqfhytyhivltamujd...@forum.dlang.org
https://issues.dlang.org/show_bug.cgi?id=18380
https://dlang.org/changelog/2.078.0.html#fix16997
However I still don't see the problem with regards to unsigned
types.
Why is it necessary to promote a ushort or ubyte to int for the
purpose of shifting or the one's complement ?
At least the code at the bottom of the post seems to produce
correct results.
One problem I see with the bug fix is that, AFAIK, the int type
in C is not a fixed bit type like it is in D where it is defined
to be 32 bit and therefore casting to int in D can't really
reproduce the C behavior. What am I missing ?
Back to my container.
* Using a 32 bit type, i.e. uint, everything compiles fine.
* Using a 16 or 8 bit type, i.e. ushort and ubyte, the compiler
complains with -preview=intpromote for the pragmas and errors out
on assignments of the same types.
i.e. e.g.
alias handle_t = ushort;
enum handle_t MASK = 0x8000;
handle_t handle = ~MASK; // the error message is basically:
[value is promoted to int and] 32769 can't be assigned to ushort
* Using a 64 bit type, i.e. ulong, the whole thing blows up
because the compiler pro-, or rather, demotes the ulong to int
and int << 40 is obviously violating a constraint of 0..31 for
32bit types.
void main()
{
import std.conv: to;
import std.stdio;
alias t = ushort;
enum t m = 0x8000;
pragma (msg, m.to!string(16));
pragma (msg, (~m).to!string(16));
pragma (msg, (cast(int)m).to!string(16));
pragma (msg, (~cast(int)m).to!string(16));
}
2.063 : Success with output:
-----
8000
7FFF
8000
FFFFFFFFFFFF7FFF
-----
2.064 to 2.077.1: Success with output:
-----
8000
7FFF
8000
FFFF7FFF
-----
2.078.1 to 2.084.1: Success with output:
-----
8000
onlineapp.d(8): Deprecation: integral promotion not done for
`~cast(ushort)32768u`, use '-transition=intpromote' switch or
`~cast(int)(cast(ushort)32768u)`
7FFF
8000
FFFF7FFF
-----
Apart from the fact that I end up with an int, which causes all
kinds of havoc and the annoyance that i need to cast a ushort to
ushort to be able to assign it to a ushort, it appears to me that
all the results are correct.