C array types are weird
anselmschueler.comC array types are weird because C doesn't really need arrays. It's not what C was about.
But if you designed a language in the era where Fortran, THE array language, reigned supreme, nobody would use your language. The mindshare Fortran had is difficult to convey now, half a century later.
Think of it like making a chatbot today and not mentioning AI or LLMs, that's what making a language without arrays would have felt like in 1970.
In practice, the [static n] notation can give you useful warnings and bounds checking.
https://godbolt.org/z/PzcjW4zKK
And while the (*array_ptr)[3] notation take a moment to get used to, it is very logical. If you have a pointer to an array, you dereference it first and then indx into it. Again, useful for bounds checking: https://godbolt.org/z/ao1so9KP7
I know of this notations but I don't see many people using [static n].
Not sure why, maybe it doesn't feel like C anymore, maybe it feels hacky?
typically if you're passed an array you'd want to get more anyway, so you'd get passed a struct. Not sure.
What is **int[3][5]
A pointer to a pointer to a pointer to a pointer of integers.
A syntax error. You need a variable name, not a type name, in the middle.
And if you want 'int **arr[a][b]', it's a value that when you say 'x = **arr[m][n]', will evaluate to an int and assign it to x. Postfix has higher precedence than prefix.
or a rejected PR
There is a history to it; in one of the predecessor languages, like B, Ritchie actually had arrays that had a hidden pointer to their start. The "array to pointer decay" was actually a real operation that loaded an address from memory, and it was possible to twiddle the bits to relocate an array. One problem with it was no way to initialize such a pointer field that would allow an array to live in dynamically allocated storage (no constructors in the language).
So in short, the bad design (array values produce pointers) was informed by conceptual compability with an earlier design in which that was literally happening.
This is one of the things that I feel is an inappropriate abstraction that is around for historical reasons. When I do FFI to call C from rust, I usually wrap the generated API (Which is pointer based) into rust's &[] array syntax. Arrays/lists/Vecs etc in most non-C languages feel like an abstraction over a collection of items; I feel like C's exposing the pointer directly is taking a low-level memory/MMIO operation and inserting it into business logic. Conceptually, I like to keep them separate; pointers for writing drivers, accessing registers, writing to flash memory etc. Arrays/lists/vecs for higher level operations on collections.
Tangent: I have a pet theory that part of Zig's raison d'etre is to fix some of the problems with C, while accommodating its pointer-based data structures, and the resulting patterns.
This talk – "Programming without pointers" – by Andrew Kelley may be interesting to you.
https://www.hytradboi.com/2025/05c72e39-c07e-41bc-ac40-85e83...
Learning to program with pointers is enormously useful. It's simply bad software engineering to not use typing to enforce constraints on access to pointers (or addresses, or however you'd like to term them)
IIRC that talk of about using indices (u32) to represent data in an array. That is orthogonal to representing that information in the type system since you can just type the index
It still cracks me up that 3[x] and x[3] mean the same thing in C.
Paging walter bright
C's biggest mistake.
But in other news most don't know that a[3] == 3[a]
I didn't understand why a[3] == 3[a], but i found this stackoverflow that explains it.
https://stackoverflow.com/a/16163840
In C a[i] is converted to *(a+i) internally. i[a] is converted to *(i+a). Array names also act as pointers in c. so (a+i) or (i+a) give an address (using pointer arithmetic) that is dereferenced using
Even more irrelevant than the array type
there's no array type in c
Yes it does. It just decays to a pointer at the slightest touch.
So why are we discussing it
Because doing a dance to avoid it decaying conveys better information to both the compiler and downstream users of your code.
Why are we still discussing c in 2026? Why are you intentionally hamstringing yourself unless you're using fucking hp-ux
Embedded programming is still in C for a lot of micro controllers and whatnot. If you’re programming with limited resources it’s essential to understand pointers and arrays. Likely you won’t be doing anything useful without them
As always, the TIOBE Index is of dubious value. The fact that it ranks Delphi above both Go and Rust should give you an idea of why.
Yeah it's rather odd, also jumps like this in ADA makes you wonder
p.s. in case you don't want to follow the link, number 2 on the list