# Constant expressions, part III

### March 19, 2024

Did you miss yesterday’s Ask-me-anything session? You probably did. I had about 10-15 people there. But even with a small group, we had a ton of great questions! The Q&A session lasted about an hour, and covered topics such as book recommendations for going deeper into Go, what project to build to learn concurrency, and much more. Catch the replay on YouTube.

Let’s continue our discussion of constant expressions, with some more miscellaneous rules:

#### Constant expressions

The divisor of a constant division or remainder operation must not be zero:

``````3.14 / 0.0   // illegal: division by zero
``````

I don’t think this needs any explanation.

The values of typed constants must always be accurately representable by values of the constant type. The following constant expressions are illegal:

``````uint(-1)     // -1 cannot be represented as a uint
int(3.14)    // 3.14 cannot be represented as an int
int64(Huge)  // 1267650600228229401496703205376 cannot be represented as an int64
Four * 300   // operand 300 cannot be represented as an int8 (type of Four)
Four * 100   // product 400 cannot be represented as an int8 (type of Four)
``````

Recall that constants can be both typed and untyped:

``````const x = "foo"         // Untyped string constant
const y = string("foo") // Typed string constant

type MyString string

const z = MyString("foo") // Typed string constant
``````

So the above rule is just the natural and obvious application of Go’s representability rules, as they apply to conversion between typed and untyped constants.

The mask used by the unary bitwise complement operator `^` matches the rule for non-constants: the mask is all 1s for unsigned constants and -1 for signed and untyped constants.

``````^1         // untyped integer constant, equal to -2
uint8(^1)  // illegal: same as uint8(-2), -2 cannot be represented as a uint8
^uint8(1)  // typed uint8 constant, same as 0xFF ^ uint8(1) = uint8(0xFE)
int8(^1)   // same as int8(-2)
^int8(1)   // same as -1 ^ int8(1) = -2
``````

Nothing new to cover here. The same rules that apply to non-constants apply to constants, with regard to the `^` operator.

And one final note before we move beyond this topic, just re-iterating what I said yesterday about the optional rounding of some constants:

Implementation restriction: A compiler may use rounding while computing untyped floating-point or complex constant expressions; see the implementation restriction in the section on constants. This rounding may cause a floating-point constant expression to be invalid in an integer context, even if it would be integral when calculated using infinite precision, and vice versa.

Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)