<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/the-c-clockwise-spiral-rule--xkrz8ad56" -->

---
title: The C ``Clockwise/Spiral Rule'' | daily.dev
description: The Clockwise/Spiral Rule is a technique for mentally parsing any C declaration. By starting at the identifier and spiraling clockwise through the declaration,...
canonical: https://daily.dev/posts/the-c-clockwise-spiral-rule--xkrz8ad56
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: The C ``Clockwise/Spiral Rule'' | daily.dev
og:description: The Clockwise/Spiral Rule is a technique for mentally parsing any C declaration. By starting at the identifier and spiraling clockwise through the declaration,...
og:url: https://daily.dev/posts/the-c-clockwise-spiral-rule--xkrz8ad56
og:image: https://api.daily.dev/og/posts/xkrZ8Ad56.png
og:image:alt: The C ``Clockwise/Spiral Rule''
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# The C ``Clockwise/Spiral Rule''

**[Hacker News](https://daily.dev/sources/hn)** · 3 min read · 0 upvotes · 0 comments

## Summary

The Clockwise/Spiral Rule is a technique for mentally parsing any C declaration. By starting at the identifier and spiraling clockwise through the declaration, reading right-then-left at each level, you can decode complex types like arrays of pointers, function pointers, and pointers to functions returning pointers. Three worked examples demonstrate the method: a simple array of char pointers, a function pointer, and the notoriously complex `signal` function signature. The rule also applies to `const` and `volatile` qualifiers.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://c-faq.com/decl/spiral.anderson.html>

## Community take

How the wider developer community reacted, aggregated from 5 discussions and 216 comments across hackernews (as of 2026-07-31).

**TL;DR:** The community largely agrees the Clockwise/Spiral Rule is flawed or misleading, with most commenters preferring the 'declaration follows use' principle or the Right-Left Rule as more correct and intuitive alternatives; a lively side thread debates C parser implementation challenges.

**Sentiment:** 25% positive · 45% mixed · 30% skeptical

**The case for**

- The spiral rule gives beginners a memorable starting point for tackling complex C declarations.
- Tools like cdecl.org or the `cdecl` package provide a practical fallback for anyone struggling with complex declarations.

**The pushback**

- The spiral rule is technically incorrect for types involving pointer-to-pointer or array-of-array, as demonstrated with a concrete counter-example.
- The 'declaration follows use' principle is widely considered a more correct and elegant explanation of C declaration syntax.
- The Right-Left Rule (right-left.rule) is cited as a correct algorithm that the spiral rule only approximates.
- C's declaration syntax is inherently confusing enough that a mnemonic rule is needed at all, which commenters see as a language design flaw.
- The `int* a, b` pitfall shows that even common conventions around pointer syntax can be misleading.

**By community**

- hackernews (mixed): Commenters are split between finding the spiral rule a useful heuristic and pointing out it is technically incorrect, with strong preference for 'declaration follows use' or the Right-Left Rule as superior alternatives.

**Hottest debate:** Whether the Clockwise/Spiral Rule is a valid teaching tool or an outright incorrect rule that should be replaced by 'declaration follows use' or the Right-Left Rule.

**Open questions**

- Is there a clean, correct, and memorable rule for parsing C declarations that works for all cases including pointer-to-pointer and array-of-array?
- Should complex C declarations always be broken up with typedefs rather than relying on any parsing rule?

**Highlights**

> The spiral rule works only if there is no pointer to pointer or array of array in the type. In other words it is an incorrect rule. But take this for example:         +----------------------------+         | +-----------------------+  |         | | +------------------+  |  |         | | | +-------------+  |  |  |         | | | | +--------+  |  |  |  |         | | | | |  +--+  |  |  |  |  |         | | | | |  ^  |  |  |  |  |  |     int * * ¦ ¦ ¦ VAR[1][2][3] |  |  |      ^  | | | | |     |  |  |  |  |  |      |  | | | | +-----+  |  |  |  |  |      |  | | | +----------+  |  |  |  |      |  | | +---------------+  |  |  |      |  | ---------------------+  |  |      |  +-------------------------+  |      +-------------------------------+ The type of VAR 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. To make the spiral correct it has to skip the pointer specifiers in the first three loops. This is marked by ¦. 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 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.
> — [palotasb on hackernews · 4 comments](https://news.ycombinator.com/item?id=42565085)

> After implementing (parts of) a recursive descent parser for C, I had a sudden enlightenment about how easy it is to understand C declarations once you get the basic principle. There's already a comment on this  (https://news.ycombinator.com/item?id=42565459), but I'll try to go into a little more detail. A lot of people start with the idea that the syntax of C declarations is '<type> <variable_name>'. This works fine for simple cases, but it's completely wrong. What a declaration like 'int x' actually means is the following:     declare a variable x of a type such that the expression x is of type int In such a simple case this seems unnecessarily long-winded, but now let's look at a more complex case:     int (*p[4]) (int x, int y);          declare a variable p of a type such that (*p[i])(x,y) is of type int If dereferencing the ith element of p and then calling the result with two arguments gives us an int, then p must be an array of pointers to functions that take two arguments and return int. If you saw the expression '(*p[i])(x,y)' in some code, you'd have no difficulty figuring out that p must be an array of function pointers. So you needn't have any difficulty when reading the declaration either. One slightly confusing thing here is that the nesting of the expression syntax is the opposite of the nesting of the type. The expression is     funcall(deref(array_index(p, i)), [x, y]) whereas the type is     array_of(pointer_to(function(args: [int, int], returning: int))) This makes sense once you understand that the expression is to be interpreted just as a normal expression. The first thing you do with an array of something is index into it. So indexation is going to be the most deeply nested part of the expression, even though the outermost layer of the type is 'array of ___'. One additional source of confusion is the '*' operator and the need for additional parentheses in function pointer declarations. In C, function pointers dereference to themselves, so 'p()' and '(*p)()' are equivalent if p is a function pointer. However, in a type declaration you need something to distinguish a function pointer from a function, so the '*' has to be present. Why can't we just write 'int *p[4](int x, int y)' in the example above? Because of how the operator precedence rules work. That expression is equivalent to '*(p[4](x,y))', so it would declare an array of functions returning pointers to integers. (You can't declare an array of functions in C, so that's invalid.) Ad-hoc rules for interpreting C declarations miss the genius of their underlying concept. You already know all the syntax you need to understand a C type declaration! It's just C expression syntax.
> — [foldr on hackernews · 1 comments](https://news.ycombinator.com/item?id=42565725)

> Being taught this rule in undergrad really hampered my appreciation of C. As I've said in a previous comment, the real key that unlocked understanding C declarations for me is the mantra "declaration follows use." You declare a variable in C in exactly the same way you would use it: if you know how to use a variable, then you know how to read and write a declaration for it. Once I  understood this elegant idea, it became hard to enjoy using statically typed languages that eschew it. It is explained in more detail at this link: https://eigenstate.org/notes/c-decl
> — [pcfwik on hackernews · 3 comments](https://news.ycombinator.com/item?id=49125262)

> 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 sometimes called the "right-left rule": https://cseweb.ucsd.edu/~gbournou/CSE131/rt_lt.rule.html).
> — [stephencanon on hackernews · 2 comments](https://news.ycombinator.com/item?id=49125153)

> I just spent a week trying to write a parser for C declarations. Recursive Descent didn't work, Top Down Operator Precedence didn't work, I finally found an simple implementation of cdecl in K&R2, but it printed out textual description instead of creating an AST. Converting it to create an AST was a whole different challenge. In the end, I got it working by adding the idea of a blank-type and doing some tree inversions (almost using each AST as a program that executes over the nested chunk of AST). It was only about 200 lines of code, and yet never have I been happier to finish a solution and never having to think about it again.
> — [HexDecOctBin on hackernews · 5 comments](https://news.ycombinator.com/item?id=42565120)

**Source threads**

- [hackernews](https://news.ycombinator.com/item?id=33066184) · 1 points · 0 comments
- [hackernews](https://news.ycombinator.com/item?id=34322586) · 1 points · 0 comments
- [hackernews](https://news.ycombinator.com/item?id=42290736) · 2 points · 0 comments
- [hackernews](https://news.ycombinator.com/item?id=42564861) · 39 points · 150 comments
- [hackernews](https://news.ycombinator.com/item?id=49123199) · 49 points · 66 comments

## Similar posts on daily.dev

- [Getting silly with C, part &\(\(int\*\)-8\)\[3\]](https://daily.dev/posts/getting-silly-with-c-part-int--8-3--vlgaijam6) · Lobsters · 14 upvotes · 3 comments
- [CSS-Tricks](https://daily.dev/posts/css-tricks-gktqweqqg) · CSS-Tricks · 10 upvotes · 1 comments
- [six thoughts on generating c — wingolog](https://daily.dev/posts/six-thoughts-on-generating-c-wingolog-kbg48lywq) · Hacker News · 0 upvotes · 0 comments

---

Tags: [#c](https://daily.dev/tags/c)

[View this post on daily.dev](https://daily.dev/posts/the-c-clockwise-spiral-rule--xkrz8ad56)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"The C ``Clockwise/Spiral Rule''","url":"https://daily.dev/posts/the-c-clockwise-spiral-rule--xkrz8ad56","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/the-c-clockwise-spiral-rule--xkrz8ad56"},"datePublished":"2026-07-31T17:38:17.445Z","dateModified":"2026-07-31T19:30:57.792Z","description":"The Clockwise/Spiral Rule is a technique for mentally parsing any C declaration. By starting at the identifier and spiraling clockwise through the declaration,...","image":"https://media.daily.dev/image/upload/s--ZrL_HSsR--/f_auto/v1722860399/public/Placeholder%2006","thumbnailUrl":"https://media.daily.dev/image/upload/s--ZrL_HSsR--/f_auto/v1722860399/public/Placeholder%2006","isAccessibleForFree":true,"articleSection":"Hacker News","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Hacker News","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/hn","url":"https://daily.dev/sources/hn"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/the-c-clockwise-spiral-rule--xkrz8ad56","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"c","timeRequired":"PT3M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Hacker News","item":"https://daily.dev/sources/hn"},{"@type":"ListItem","position":3,"name":"The C ``Clockwise/Spiral Rule''"}]}
```

