Live data from Hacker News

Clockwise/Spiral Rule (1994)

c-faq.com

41–50 of 59 posts

Re: Clockwise/Spiral Rule (1994)

#41
post #34
post #26

Earlier quoted context omitted.

I assume he means multi-dimensional arrays: std::array , 5> array_of_ints; int c_style_array[5][3]; But the C-style array is more readable, so I am not sure what the complaint really is about.

No, I think he means that for any given type, you can wrap it in an array the same way. Your example is demobstating that it even works recursively, but it works in the simple case too by wrapping "int" in an array to get an array of ints. There's no need to jump back and forth between each side when adding new layers (which gets described as a "spiral", but in a single line of code, I'd argue that it's really just j…

If I would add another array, it would look like:

int c_style_array[2][5][3];

There is also no jumping back and forth. C declarations are also recursively constructed. One can complain about the irregularity of pointers syntax.

Re: Clockwise/Spiral Rule (1994)

#42
post #29
post #21

Earlier quoted context omitted.

> int *w; But some misguided style guides demand the misleading `int* w;`, and then act surprised by `int* w, x`;

I split the difference and write it "int*w". (Most style guides tell you to declare one name per line anyway...)

I have seen `int * w` in the real world.

I'm sad now.

Re: Clockwise/Spiral Rule (1994)

#43
post #21
post #17

Earlier quoted context omitted.

The way I've learned to read it is int v; means that `v` is an `int`. int *w; means that `*w` is an `int`, meaning `w` is a pointer to an `int`. int *y[5] (note that `◌[]` has higher precedence than `*◌`, so this is `*(y[5])`) means that `*y[5]` is an `int`, so `y[5]` is a pointer to an `int`, meaning `y` is an array of `int` pointers. int (*(*kitchensink[5])(int, int))[6]; means that `(*(*kitchensink[5])(int, int))[…

> int *w; But some misguided style guides demand the misleading `int* w;`, and then act surprised by `int* w, x`;

Those style guides would also disallow having multiple declarators in a single declaration.

Re: Clockwise/Spiral Rule (1994)

#45
Related. Others?

C "clockwise/spiral" rule to understand declarations - https://news.ycombinator.com/item?id=42564861 - Jan 2025 (75 comments)

Clockwise/Spiral Rule - https://news.ycombinator.com/item?id=25494219 - Dec 2020 (16 comments)

The Clockwise/Spiral Rule of C declarations - https://news.ycombinator.com/item?id=12775735 - Oct 2016 (68 comments)

The “Clockwise/Spiral Rule” - https://news.ycombinator.com/item?id=8648287 - Nov 2014 (26 comments)

The Clockwise/Spiral Rule - https://news.ycombinator.com/item?id=6471202 - Sept 2013 (7 comments)

The "Clockwise/Spiral Rule" in C - https://news.ycombinator.com/item?id=5079787 - Jan 2013 (45 comments)

Re: Clockwise/Spiral Rule (1994)

#46
post #38

My ideal syntax for function pointers is: fn signal(signum: int, fp: fn(int -> void)) -> fn(int -> void) It keeps the parameter and return types inside, makes it obvious that it's a function using the fn keyword (or func or whatever), short and readable. When you add more parameters you get `fn(int, char -> int)`. That's the only sane way to handle it and it also supports multiple return values if you want them. Bonu…

> My ideal syntax for function pointers is

this is actually very Kotlin, in Kotlin it'd be `val lambda: (Int, Char) -> Int = { myInt, myChar -> return 69 }`

Zig has also come very close:

  const Call2Op = *const fn (a: i8, b: i8) i8;
  fn doOp(fnCall: Call2Op, op1: i8, op2: i8) i8 {
      return fnCall(op1, op2);
  }
> Every language should either have a pipe operator or let you call any function with method syntax

there is a nicety in Zig that may help: `fn1(p1, ...)` is the same as `fn1.p1()`, so `fn2(fn1(p1))` can be unfolded into `p1.fn1().fn2()`

Re: Clockwise/Spiral Rule (1994)

#47
post #3

> "str is an array 10 of pointers to char" Wow, imagine if it was possible to actually use a language like that do declare the type of the variable like that? Something like str: array [0..9] of ^Char; or even var str [10]*uint8 Just imagine...

Yeah, Pascal is very readable, and ^Char is nicer than char* even if inconsistently concise (might expect "pointer to Char").

Re: Clockwise/Spiral Rule (1994)

#49

This comes up every so often, and while it's sort of almost true and attractive, it isn't actually correct. The correct rule is "follow the C grammar". An easier to remember and also correct rule is "start at the identifier being declared; work outwards from that point, reading right until you hit a closing parenthesis, then left until you hit the corresponding open parenthesis, then resume reading right..." (this is…

Why would you do that? Ignoring for the moment arguments of prototypes and sizes of arrays, read C declarations the way they were designed: “char *a[ ]” means that the expression *a[ ] has type char; “char (*a( ))[ ]” means that the expression (*a( ))[ ] has type char; and so on. Then you apply the normal precedence rules for expressions, and in this case only knowing them for the prefix and postfix operators is suff…

That’s exactly the same rule with more words (postfix = right, prefix = left).

Re: Clockwise/Spiral Rule (1994)

#50

Earlier quoted context omitted.

Why would you do that? Ignoring for the moment arguments of prototypes and sizes of arrays, read C declarations the way they were designed: “char *a[ ]” means that the expression *a[ ] has type char; “char (*a( ))[ ]” means that the expression (*a( ))[ ] has type char; and so on. Then you apply the normal precedence rules for expressions, and in this case only knowing them for the prefix and postfix operators is suff…

That’s exactly the same rule with more words (postfix = right, prefix = left).

I mean, yes, you’ve given a correct algorithm for parsing this simple precedence grammar, but it still leaves the impression that there’s something new to learn in addition to C expressions, whereas the whole point of the declaration syntax is that there largely isn’t.
Post reply on HN