Endianness - How to test code for portability
Dennis
dkorpel at gmail.com
Fri Mar 12 10:26:55 UTC 2021
On Friday, 12 March 2021 at 05:53:40 UTC, Preetpal wrote:
> This is not an important issue to me but I was just curious to
> see if anyone actually tests for portability issues related to
> endianness by compiling their D Lang code for a big endian
> architecture and actually running it on that system.
I have a png decoder, and I often avoid a dependency on
endianness by using bit-shifts instead of casts. For example,
this code reads a big-endian integer and returns a native-endian
integer, regardless of architecture:
```
uint readUintBe(in ubyte[] s) {
return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
}
```
There is a part in the decompression where a ubyte[] is cast to a
uint[] for performance, and it assumes a little-endian byte
order. There is a fallback for big-endian architectures, but also
for CTFE, where reinterpretation through overlapped fields or
array casts is not allowed. So the code is structured like this:
```
version(BigEndian) {
private enum bigEndian = true;
} else {
private enum bigEndian = false;
}
int parse(in ubyte[] data) {
if (__ctfe || bigEndian) {
// Portable code
} else {
// Little-endian optimized code
}
}
```
Then you can test both at runtime and compile time:
```
unittest {
ubyte[] testData = [...];
assert(parse(testData) == 3);
static assert(parse(testData) == 3);
}
```
So no, I don't have a big-endian computer I can test it on, but I
do test with CTFE, so I'm pretty sure I'm not relying on a
specific byte order.
More information about the Digitalmars-d-learn
mailing list