3 ms·
Any time the spiral rule comes up, I like to point out that it's wrong. It is instructive in a way because one learns more about C declaration syntax, but it is
by palotasb 5y ago
Any time the spiral rule comes up, I like to point out that it's wrong. It is instructive in a way because one learns more about C declaration syntax, but it is even more instructive to recognize why it is wrong.
The spiral rule works only if there is no pointer to pointer or array of array in the type. But take this for example:
+----------------------------+
| +-----------------------+ |
| | +------------------+ | |
| | | +-------------+ | | |
| | | | +--------+ | | | |
| | | | | +--+ | | | | |
| | | | | ^ | | | | | |
int * * ¦ ¦ ¦ xxx[1][2][3] | | |
^ | | | | | | | | | | |
| | | | | +-----+ | | | | |
| | | | +----------+ | | | |
| | | +---------------+ | | |
| | ---------------------+ | |
| +-------------------------+ |
+-------------------------------+
The type of xxx is a [1-element] array of [2-element] array of [3-element] array of pointer to pointer to ints. I drew a spiral that passes through each specifier in the correct order.
Notice that to make the spiral correct it has to skip the pointer specifiers in the first three loops. This is marked by ¦. This is not mentioned in the original spiral rules and one could be forgiven to parse the expression as xxx -> [1] -> pointer -> [2] -> etc. following a spiral that doesn't skip the pointers.
The Right-Left Rule is quoted less frequently on HN but it's a correct algorithm for deciphering C types: http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html
The spiral rule can be modified to process all array specifiers before all pointer specifiers, but then you'd have to specify that the order to do so is right and then left. At that point it's just the Right-Left Rule.
- userbinator 5y agoThe summary is "array and function has higher precedence than pointer, and parentheses override all". This explains why int *f(); is a function returning pointer to int, while int (*f)() is a pointer to function returning int. Likewise, int *a[] is an array of pointer to int, while int (*a)[] is a pointer to array of int.
- pmarreck 5y agobetween things like this and the pre- and post-increment/decrement operators, it's shocking that C code generates so many security holes ;)
- nicoburns 5y agoArgh! All of these examples seem backwards to me. Why on earth isn't "a pointer to an array of int" something like: *(int[])
- userbinator 5y agoBecause of how precedence works --- you start from the inside and work outwards, the same as when evaluating ordinary maths expressions. "Pointer to array of int" means you dereference it first to get an array of ints, then index to get an int.