Mutable and Constant Pointer Semantics

Pointers carry many distinct characteristics. One important characteristic is the mutability via the const keyword which controls how addresses and data can be mutated.

There are 4 basic const combinations as it relates to pointers.

var x: *T         // x is a mutable address to mutable data.
const x: *T       // x is a constant address to mutable data.
var x: *const T   // x is a mutable address to constant data.
const x: *const T // x is a constant address to constant data.

Much like a physical location, a valid pointer refers to a region that has been denoted with an address. In other words, we can find that region by following its address (much like locating a monument using coordinates).

The dual const qualification means we can either change the address, or change the thing at the address, or some combination of the two.

Example 1: Constant address to mutable data

var x: usize = 42;
var y: usize = 43;

const ptr = &x; // the address is const, but the data is not.

ptr = &y; // this fails because we cannot change the address.

ptr.* += 1; // this succeeds because we can change the data.

Example 2: Mutable address to constant data

const x: usize = 42;
const y: usize = 43;

var ptr = &x; // the data is const, but the address is not.

ptr = &y; // this succeeds because we can change the address.

ptr.* += 1; // this fails because we cannot change the data.

Example 3: Mutable address to mutable data

var x: usize = 42;
var y: usize = 43;

var ptr = &x; // both the data and the address are mutable.

ptr = &y; // this succeeds because we can change the address.

ptr.* += 1; // this succeeds because we can change the data.

Example 4: Constant address to constant data

const x: usize = 42;
const y: usize = 43;

const ptr = &x; // both the data and the address are constant.

ptr = &y; // this fails because we cannot change the address.

ptr.* += 1; // this fails because we cannot change the data.

Explicitly declaring mutability

Mutable data can be viewed as constant by using the const keyword on the pointer explicitly.

// the data itself is mutable
var x: usize = 42;

// the pointer sees the data as const
const ptr: *const usize = &x;

Note that this follows typical rules surrounding const - const qualification cannot be dropped without using @constCast.

// the data itself is const
const x: usize = 42;

// this fails because the data is const
const ptr: *usize = &x;
7 Likes

I’m a bit confused. What did you mean here exactly? Did you mean

  • dual nature (can appear both before : and after :) of const qualifier
    or
  • const x: *const T case, double const
    ?

Sure - good question.

By dual const (dual meaning two of something), I mean that const can show up twice in a single type declaration. Now, we know that you can have more than two consts…

const x: []const []const u8 is 3 qualifiers and denotes a constant slice to constant slices of u8’s. The point of this Doc though is to give a basic understanding of the most common pointer qualifiers people encounter (especially in the beginning).

const _: *const _

Do you have a suggestion to make this more clear?

Also, we could edit this article to add more content too for more advanced cases -
Docs are open ended after all.

Well, English is not my native… ok, I’ll try…
“As we can see from the examples above, const qualifier can be used on both sides of : when declaring pointers. When it is used on the left side, before a variable (argh…) name (const ptr : ...), it denotes immutability of the pointer itself, and when it is used on the right side (... : *const T;), it denotes immutability of data pointed to by that pointer”.

something like this :slight_smile:

3 Likes

Thanks! I’ll get this formatted and included tomorrow.

4 posts were split to a new topic: Alternative declaration syntax