2

The closest I can get is runtime.GOARCH, but that might also give arm, which could be either 32 or 64 bit.


I only care how this program was built, not whether the OS also supports 64-bit executables. e.g. for ARM mode on an AArch64 CPU or 32-bit compat mode on an x86-64 CPU, I still want 32 because that's the mode this program is running in.

Related: Detect OS x86 or x64, when compiled as x86 in GO is about detecting what the OS supports, e.g. for maybe running a differently-compiled executable.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
EMBLEM
  • 2,207
  • 4
  • 24
  • 32
  • `runtime.GOARCH` will give you the architecture the program was compiled to run on. To get the actual systems' architecture details, you'll probably end up having to check `runtime.GOOS`, and perform a platform specific system call. – Elias Van Ootegem Mar 16 '16 at 10:59
  • This question originally looked like it was about detecting the OS, but the answers, including the accepted one, were about detecting the compiler-target bitness. I edited it to make the question match the answers, because this is also a potentially useful thing. That's why there are comments about this detection not matching the OS. – Peter Cordes Feb 18 '21 at 06:49

2 Answers2

6

Use GOARCH for arm: arm (ARM) and arm64 (AArch64),

Optional environment variables

$GOOS and $GOARCH

The name of the target operating system and compilation architecture. These default to the values of $GOHOSTOS and $GOHOSTARCH respectively (described below).

Choices for $GOOS are

$GOOS     $GOARCH
darwin    386
darwin    amd64
darwin    arm
darwin    arm64
dragonfly     amd64
freebsd   386
freebsd   amd64
freebsd   arm
linux     386
linux     amd64
linux     arm
linux     arm64
linux     ppc64
linux     ppc64le
linux     mips64
linux     mips64le
netbsd    386
netbsd    amd64
netbsd    arm
openbsd   386
openbsd   amd64
openbsd   arm
plan9     386
plan9     amd64
solaris   amd64
windows   386
windows   amd64
peterSO
  • 158,998
  • 31
  • 281
  • 276
  • 2
    IIUC, `runtime.GOARCH` would return the architecture of the built *program* being executed. Since some arches, namely, Intel/AMD's 64-bit ISAs, allow running 32-bit programs on 64-bit kernels, so if the OP really wanted to know the architecture of the OS currently executing their Go program, the approach to figuring this out should supposedly be different (and, I'm afraid, platform-specific). – kostix Mar 16 '16 at 10:54
3
const is64Bit = uint64(^uintptr(0)) == ^uint64(0)

This works because if uintptr is 32 bits, ^uintptr(0) will be 0xffffffff rather than 0xffffffffffffffff.

^uint64(0) will always be 0xffffffffffffffff regardless of 32 or 64 bit architectures.

Karl
  • 14,434
  • 9
  • 44
  • 61
  • Wouldn't `uintptr` always be 32-bit in 32-bit code, even when running under a 64-bit OS? (e.g. i386 code under an x86-64 long mode kernel, or ARM32 code under an AArch64 kernel, are the main real-world use-cases for this. e.g. where you want to know which version of another executable you can run.) – Peter Cordes Feb 18 '21 at 06:33
  • But apparently that's what this question actually wants, given the accepted answer. So I'll retitle the question. – Peter Cordes Feb 18 '21 at 06:35
  • Note that this will report non-64-bit even for ILP32 ABIs in 64-bit mode. So this is good for figuring out if pointers are 64-bit, but not for figuring out if 64-bit integer stuff can be done fully efficiently. (e.g. AArch64 ILP32 uses 32-bit pointers in 64-bit mode to save space, same as [Linux x32](https://en.wikipedia.org/wiki/X32_ABI) on x86-64) – Peter Cordes Feb 18 '21 at 06:51
  • Hmm interesting. Then perhaps a second test `uint64(^uint(0)) == ^uint64(0)` would give a fuller picture. – Karl Feb 19 '21 at 08:29
  • I wouldn't expect `uint` to be 64-bit, if Go sizes it like C compilers choose the size of `unsigned int`. ILP32 ABIs like x32 will have 32-bit `uint` as well, I'd expect. – Peter Cordes Feb 19 '21 at 08:31
  • But generally for anyone using this kind of trick, they're really interested in whether uint will be 32 or 64 bit, and whether uintptr will be 32 or 64 bit. I've encountered this issue many times when trying to deal with for example words in a big.Int – Karl Feb 19 '21 at 08:32
  • I don't know Go, but if you're writing your own extended-precision stuff, you generally want to work in chunks as large as efficiently possible, even if that's wider than pointer width. (Or maybe just always 64-bit chunks, even if that means the compiler has to use a pair of 32-bit `add/adc` instructions in a 32-bit build). If you want to know whether `uint64` is as efficient as a 32-bit integer type for most arithmetic, in C/C++ AFAIK there's no easy portable way to detect that without false negatives on ILP32 ABIs. uintptr being 64-bit is a sure sign that it *is* efficient, though. – Peter Cordes Feb 19 '21 at 08:42