filharmonista

Posted on

# Pointers and constness in Zig (and why it is confusing to a C programmer)

## C pointers

If you, like me, are a C programmer you might have been asked on one of your job interviews a question like:

What is the difference between those four pointers?

``````uint8_t * p1;
const uint8_t * p2;
uint8_t * const p3;
const uint8_t * const p4;
``````

And then you would respond with something like:

The first one is a pointer to uint8_t. One can modify the pointer value itself as well as the uint8_t value it points to.
The second one is a pointer to const uint8_t. One can modify only the pointer value itself. One cannot modify the value of the uint8_t it points to (as it is const uint8_t).
The third one is a const pointer to uint8_t. One cannot modify the pointer value itself (as it is a const pointer). Only the value of the uint8_t the pointer points to can be modified.
The fourth one is a const pointer to a const uint8_t. One cannot modify neither the pointer value itself nor the value of the const uint8_t it points to.

That is a lot of words. Let us look at the code for better understanding (using the pointers defined previously):

``````// we assume pointers are 32-bits long
p1 = (uint8_t *)0x11115555; // OK
*p1 = 3; // OK

p2 = (uint8_t *)0x11115555; // OK
*p2 = 3; // not OK, pointer points to a const value

p3 = (uint8_t *)0x11115555; // not OK, pointer is const
*p3 = 3; // OK

p4 = (uint8_t *)0x11115555; // not OK, pointer is const
*p4 = 3; // not OK, pointer points to a const value
``````

At this point it should be clear to everyone what we call different type of pointer in the C world. What is a const pointer, what is a pointer to const and what is the difference between them.

## Zig pointers

When I was starting exploring Zig, I was reading some articles (like When a var really isn't a var by @gowind), watching some videos (like Solving Common Pointer Conundrums by @kristoff) and looking at the documentation.
And I could not understand how pointers and const work together in Zig. But one day I finally got it. Moreover, I got also why it was so confusing. Maybe, it was a source of @gowind's confusion when he was writing his article. Maybe, it was/is/will be a source of confusion for other C developers.

It turned out that Zig have exactly the same four variations of pointer as C:

``````var p1: *u8 = undefined;          // C pointer to u8            , uint8_t * p1
var p2: *const u8 = undefined;    // C pointer to const u8      , const uint8_t * p2
const p3: *u8 = undefined;        // C const pointer to u8      , uint8_t * const p3
const p4: *const u8 = undefined;  // C const pointer to const u8, const uint8_t * const p4
``````

There is one caveat, though. What a C developer calls pointer to const in Zig is called const pointer. One example of such terminology can be found in official documentation (see test_single_item_pointer.zig in Pointers section, where pointer to a const is described as const single-item pointer). "Const pointer" was also used several times by @kristoff in his youtube talk.

In my humble opinion using such a convention is a significant mistake for two main reasons:

1. It is utterly confusing to people who have some C background.
2. It makes is it more difficult to explain properly the whole concept (even @kristoff struggled a lot in his talk and I am not convinced how many people got it).

Additionally, it could make other concepts unclear (e.g. one could ask why it is possible to modify the value that a pointer points to, when this pointer is a function argument, therefore it should be a const pointer and Zig const pointers do not allow to modify the value they point to).

Zig provides lovely compatibility with C on many different levels. Maybe it is not a bad idea to use C-compatible terminology too?

jimying

good job

I love the grammar that Zig uses for declarations. In C that is the worst part of the language. And it is the hardest part when you teach C.

The grammar used in Zig is similar to Pascal/Modula/Oberon. Very readable. But I also wonder why the naming is not as you would read it:

``````var p1: *u8 = undefined; // variable p1 is a pointer to a u8
var p2: *const u8 = undefined; // variable p2 is a pointer to constant u8
const p3: *u8 = undefined; // constant p3 is a pointer to a u8
const p4: *const u8 = undefined; // constant p4 is a pointer to a constant u8
``````

Zaya6

Doesn’t seem to confusing to me, at least the zig types are vastly more readable

Fifnmar

That last code block is a neat mapping.

axel

Nice post! This is really helpful

Allan MacKinnon

Nice post. Thanks for summarizing!