goendianness

Any better way to check endianness in Go


I am writing a small program to check the endianness using Go:

var i int = 0x0100
ptr := unsafe.Pointer(&i)
if 0x01 == *(*byte)(ptr) {
    fmt.Println("Big Endian")
} else if 0x00 == *(*byte)(ptr) {
    fmt.Println("Little Endian")
} else {
    // ...
}

I import "unsafe" package to convert *int to *byte. But as mentioned in https://golang.org/pkg/unsafe/:

Package unsafe contains operations that step around the type safety of Go programs.

Packages that import unsafe may be non-portable and are not protected by the Go 1 compatibility guidelines.

Is there a better way to determine endianness, or do I have to use unsafe package?


Solution

  • 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...