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