Issue 24879 - Unexpected sign extension after shifting a ubyte and promoting to ulong
Summary: Unexpected sign extension after shifting a ubyte and promoting to ulong
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P3 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-11-25 09:14 UTC by Manu
Modified: 2024-11-25 11:50 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Manu 2024-11-25 09:14:52 UTC
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 anonymous4 2024-11-25 10:15:40 UTC
Well, yes, bytes[4] << 24 == 0xffffffff9a000000, try it.
Comment 2 Dennis 2024-11-25 10:46:15 UTC
`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 Manu 2024-11-25 11:36:08 UTC
Oh wow; my bad. That's so obvious in retrospect, and terrible.