Architecture-specific Numeric Types

February 21, 2023

In addition to the architecture-independent numeric types, Go provides three architecture-specific numeric types. Although there are far fewer of them, they often get a lot more usage.

Numeric Types

There is also a set of predeclared integer types with implementation-specific sizes:

uint     either 32 or 64 bits
int      same size as uint
uintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value

What does it mean for a type’s size to be architecture-dependent?

Well, it means that if you compile you code to run on, say, the 386 architecture, then int, and uint will hold 32 bits of data. But if you compile for the amd64 architecture, the same types will hold 64 bits of data.

But importantly, just because you may be compiling and running your code for the 386 architecture doesn’t mean that int and int32 are the same!

… Explicit conversions are required when different numeric types are mixed in an expression or assignment. For instance, int32 and int are not the same type even though they may have the same size on a particular architecture.

Okay, but why bother with this complexity?

In a word: efficiency.

While any CPU (not counting truly ancient ones) can handle both 32-bit and 64-bit numbers, they can’t do it with equal efficiency.

Manipulating 64-bit numbers on the 386 architecture involves manipulating two sets of 32-bit numbers, because the CPU’s native operations operate only on 32-bit numbers at a time.

So when should you use these architecture-specific types? Well, most of the time, actually. Generally, use int and uint for for loops or internal counters, unless there’s a risk of overflow (you’re counting large numbers that could exceed the min/max values of a 32-bit value), or you know you need a specific format for compatibility (i.e. writing the exact memory bits to the network or disk or similar).

Quotes from The Go Programming Language Specification, Version of January 19, 2023

Share this

Related Content

Empty structs

We finally we have enough knowledge for the EBNF format not to seem completely foreign, so let’s jump back and take a look at that, with the examples provided in the spec… Struct types … StructType = "struct" "{" { FieldDecl ";" } "}" . FieldDecl = (IdentifierList Type | EmbeddedField) [ Tag ] . EmbeddedField = [ "*" ] TypeName [ TypeArgs ] . Tag = string_lit . // An empty struct.

Struct tags

Struct types … A field declaration may be followed by an optional string literal tag, which becomes an attribute for all the fields in the corresponding field declaration. An empty tag string is equivalent to an absent tag. The tags are made visible through a reflection interface and take part in type identity for structs but are otherwise ignored. struct { x, y float64 "" // an empty tag string is like an absent tag name string "any string is permitted as a tag" _ [4]byte "ceci n'est pas un champ de structure" } // A struct corresponding to a TimeStamp protocol buffer.

Struct method promotion

Yesterday we saw an example of struct field promotion. But methods (which we haven’t really discussed yet) can also be promoted. Struct types … Given a struct type S and a named type T, promoted methods are included in the method set of the struct as follows: If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.