C array types are weird
In this article I’ll explain what I find weird about them, what I’d do differently, and ramble on a few related things.
Technically speaking, an array type T[n] (for some n) is distinct from a pointer type T * . A value of type T[n] represents a contiguous sequence of T values in memory, n long.
But you can’t actually refer to values of type T[n] . Any expression that would be of that type is immediately converted to a pointer, type T * , namely a pointer to the first element.
Since the array indexing operator arr[ix] actually operates on pointers, acting like *(arr + ix) , you can basically treat arrays like pointers.
An important instance where this doesn’t happen is in sizeof arr , which returns sizeof(T) × n.
int arr [ 3 ] = { 10 , 20 , 30 } ; int * arr_ptr = arr ; size_t arr_size = sizeof ( arr ) ; size_t ptr_size = sizeof ( arr_ptr ) ;
Additionally, in function signatures, any array type you give to an argument is actually interpreted as a pointer instead. The n denoting the size is completely discarded. That means that, as an exception to the exception, sizeof arr in a function with an argument T arr[n] will not evaluate to sizeof(T) × n.
size_t foo ( char buf [ 6 ] ) { return sizeof ( buf ) ; } char msg [ 6 ] = "!! ??" ; size_t msg_size = sizeof ( msg ) ; size_t msg_size_in_fn = foo ( msg ) ;
Note that you can write char buf[static 8] to “enforce” the length, but this just makes it undefined behaviour if you pass a pointer to a shorter array. Similar to restrict , all it does is aid the compiler in optimisation.
... continue reading