Bug 24879 – Unexpected sign extension after shifting a ubyte and promoting to ulong
Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2024-11-25T09:14:52Z
Last change time
2024-11-25T11:50:49Z
Assigned to
No Owner
Creator
Manu
Comments
Comment #0 by turkeyman — 2024-11-25T09:14:52Z
ubyte[8] bytes = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
ulong ii = cast(ulong)bytes[0] << 56 | cast(ulong)bytes[1] << 48 | cast(ulong)bytes[2] << 40 | cast(ulong)bytes[3] << 32;
ulong i = ii | bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7];
assert(ii == 0x1234567800000000); // this is correct
assert(i == 0x123456789abcdef0); // but this results in 0xFFFFFFFF9abcdef0
Weird!
Comment #1 by dfj1esp02 — 2024-11-25T10:15:40Z
Well, yes, bytes[4] << 24 == 0xffffffff9a000000, try it.
Comment #2 by dkorpel — 2024-11-25T10:46:15Z
`bytes[4] << 24` gets promoted to int, and sign extended when or'd with a ulong. The same happens in C, and D committed to having the same integer promotion rules as C, so I don't see much that can be done here. Do you have a suggestion?
Comment #3 by turkeyman — 2024-11-25T11:36:08Z
Oh wow; my bad. That's so obvious in retrospect, and terrible.