May 14, 2020 Compiler bug ? -preview=intpromote and Integral promotion rules not being followed for unary + - ~ operators | ||||
---|---|---|---|---|
| ||||
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/yqfhytyhivltamujdhgb@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. |
Copyright © 1999-2021 by the D Language Foundation