Geekly Articles each Day

The technique known as “Clockwise / Spiral Rule” (Spiral Rule Reading) allows any programmer to parse any C declaration.

Follow these simple steps:

1. Starting with an unknown element, move in a spiral / clockwise; at the same time replace the following elements with appropriate phrases:

2. Spiral / clockwise until all elements are passed.

3. You must always first resolve expressions in brackets!

#### Example 1: Simple announcement

Ask yourself what is str?

Moving in a spiral / clockwise, starting with str, and the first character that we see is '[', it means this is an array, and so:

We continue to move in a spiral / clockwise direction, and the next thing we see is the symbol '*', which means we have pointers, and so:

Moving in a spiral and see the end of the line, so move on and see the type 'char', and so:

We visited all the elements, i.e. Everything, we have disassembled this expression!

')

#### Example 2: Declaring a function pointer

Ask yourself what is fp?

Moving in a spiral / clockwise, and the first thing we see is ')'; so fp is inside brackets and we continue the spiral inside brackets and the next character is '*', and so:

We are now outside the brackets and, continuing to spiral, we see '(', ie, this is a function, and so:

Continuing to move in a spiral, we encounter the symbol '*', and so:

Continuing to move in a spiral, we meet the symbol ';', but since not all the characters have been processed yet, we continue and meet the 'char', and so:

#### Example 3: Ultimate

Ask yourself what is signal?

Notice the signal inside the parentheses, so you must first parse the expression inside! Moving in a spiral / clockwise, we see '(', and so:

Hmm, we can use the same rule on the 'fp' symbol, and so what is fp? fp is also inside the brackets, so we continue and see the '*', and so:

Moving in a spiral / clockwise, we see '(', and so:

Moving in a spiral / clockwise, we see a 'void', and so:

We ended up with fp, so let's continue with signal, and now we have:

We are still inside brackets, so the next character is a '*', and so:

We have resolved the elements inside the brackets, continuing along the spiral we get the symbol '(', and so:

Finally, we continue to move, and the last character we see is 'void', and so, our full description is this:

This rule also applies to understanding const and volatile attributes. For example:

So what is chptr?

What about this:

So what is chptr?

And finally:

So what is chptr?

Follow these simple steps:

1. Starting with an unknown element, move in a spiral / clockwise; at the same time replace the following elements with appropriate phrases:

- [X] or [] => an array of size X of type ... or an array of indefinite size of type ...
- (type1, type2) => a function that accepts types1, type2 and returns ...
- * => pointer to ...

2. Spiral / clockwise until all elements are passed.

3. You must always first resolve expressions in brackets!

`+-------+<br>`

| +-+ |<br>

| ^ | |<br>

**char** *str[ 10 ];<br>

^ ^ | |<br>

| +---+ |<br>

+-----------+<br>

Ask yourself what is str?

str is ...

Moving in a spiral / clockwise, starting with str, and the first character that we see is '[', it means this is an array, and so:

str is an array of size 10 type ...

We continue to move in a spiral / clockwise direction, and the next thing we see is the symbol '*', which means we have pointers, and so:

str is an array of size 10 type pointer to ...

Moving in a spiral and see the end of the line, so move on and see the type 'char', and so:

str is an array of size 10 of type pointer to char.

We visited all the elements, i.e. Everything, we have disassembled this expression!

')

`+--------------------+<br>`

| +---+ |<br>

| |+-+| |<br>

| |^ || |<br>

**char** *(*fp)( **int** , **float** *);<br>

^ ^ ^ || |<br>

| | +--+| |<br>

| +-----+ |<br>

+------------------------+<br>

Ask yourself what is fp?

fp is ...

Moving in a spiral / clockwise, and the first thing we see is ')'; so fp is inside brackets and we continue the spiral inside brackets and the next character is '*', and so:

fp is a pointer to ...

We are now outside the brackets and, continuing to spiral, we see '(', ie, this is a function, and so:

fp is a pointer to a function that accepts an int and a pointer to a float that returns ...

Continuing to move in a spiral, we encounter the symbol '*', and so:

fp is a pointer to a function that takes an int and a pointer to a float that returns a pointer to ...

Continuing to move in a spiral, we meet the symbol ';', but since not all the characters have been processed yet, we continue and meet the 'char', and so:

fp is a pointer to a function that accepts an int and a pointer to a float that returns a pointer to a char.

`+-----------------------------+<br>`

| +---+ |<br>

| +---+ |+-+| |<br>

| ^ | |^ || |<br>

**void** (*signal( **int** , **void** (*fp)( **int** )))( **int** );<br>

^ ^ | ^ ^ || |<br>

| +------+ | +--+| |<br>

| +--------+ |<br>

+----------------------------------+<br>

Ask yourself what is signal?

Notice the signal inside the parentheses, so you must first parse the expression inside! Moving in a spiral / clockwise, we see '(', and so:

signal is a function that accepts int and ...

Hmm, we can use the same rule on the 'fp' symbol, and so what is fp? fp is also inside the brackets, so we continue and see the '*', and so:

fp is a pointer to ...

Moving in a spiral / clockwise, we see '(', and so:

fp is a pointer to a function that accepts an int, which returns ...

Moving in a spiral / clockwise, we see a 'void', and so:

fp is a pointer to a function that accepts an int, which returns void.

We ended up with fp, so let's continue with signal, and now we have:

signal is a function that accepts an int and a pointer to a function, accepts an int, returns void, returns ...

We are still inside brackets, so the next character is a '*', and so:

signal is a function that accepts an int and a pointer to a function, accepts an int, returns void, returns a pointer to ...

We have resolved the elements inside the brackets, continuing along the spiral we get the symbol '(', and so:

signal is a function that accepts an int and a pointer to a function, accepts an int, returns void, returns a pointer to a function, accepts an int, and returns ...

Finally, we continue to move, and the last character we see is 'void', and so, our full description is this:

signal is a function that accepts an int and a pointer to a function, accepts an int, returns void, returns a pointer to a function, accepts an int, and returns a void.

This rule also applies to understanding const and volatile attributes. For example:

const char * chptr;

So what is chptr?

chptr is a pointer to char that is unchangeable.

What about this:

char * const chptr;

So what is chptr?

chptr is an immutable pointer to char.

And finally:

volatile char * const chptr;

So what is chptr?

chptr is an immutable pointer to char volatile.

Source: https://habr.com/ru/post/100104/