Any better way to check endianness in Go

Although still relying on the unsafe package, Google's TensorFlow API for Go has a nice solution (see tensor.go) for testing the endianness of your machine:

var nativeEndian binary.ByteOrder

func init() {
    buf := [2]byte{}
    *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD)

    switch buf {
    case [2]byte{0xCD, 0xAB}:
        nativeEndian = binary.LittleEndian
    case [2]byte{0xAB, 0xCD}:
        nativeEndian = binary.BigEndian
    default:
        panic("Could not determine native endianness.")
    }
}

What you want to do is architecture-specific, and Go doesn't do a whole lot to help you determine your host's byte order as far as I can tell. Your solution using unsafe pointers is probably the best you can do.

If you know the byte order you want to speak in and encode/decode accordingly, you can use the encoding/binary package for that: https://godoc.org/encoding/binary#ByteOrder

If you truly need to rely on host byte order, you might be banging your head on a design anti-pattern that you should try to avoid if possible: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html

Also here's a spirited discussion on golang-nuts about this very topic, with opinions expressed on both sides of the debate: https://groups.google.com/forum/#!topic/golang-nuts/3GEzwKfRRQw

That email thread has a suggestion by Russ Cox to just statically define the desired byte order (or the host byte order) using build constraints:

For months now our code has had:

var hbo = binary.LittleEndian // hack - we want host byte order!

so we can use encoding.Binary to read things.

Put that in a file named byteorder_amd64.go and it stops being a hack. It need not be in the standard library.

Hope that helps...

Tags:

Endianness

Go