An Engineer's Blog

Back

Intuitive Understanding of C DeclarationBlur image

Overview#

This article describes several examples of declaration in C programming considering the order of symbols, identifiers and explaining with an intuitive understanding.

For instance, converting this declaration

int (*(*func_ptr)(char *,double))[9][20];
c

to plain text English

func_ptr is pointer to function expecting (char *,double) and returning pointer to array (size 9) of array (size 20) of int.

Prerequisite#

  • Basic understanding of programming language

An understanding of C programming language syntax, data type, identifier and the concept of pointers is advantageous, but not required.

The “Right-Left” rule Intuition#

First and foremost, these symbols in C are important: asterisk ”*”, squared bracket[]”, and parenthesis()”.

Later, these can be useful to determine the correct declaration by using their translated English interpretation and their position in the declaration sentence.

SymbolInterpretationPosition
*as “pointer to”on the left side
[]as “array of”on the right side
()as “function returning”on the right side

These symbols can be interpreted in plain English whose position can also be interpreted to order all symbols

Step 1 – Find the Identifier#

Take int *p[]; as a basic example which can be interpreted straight forward by looking from the previous Symbol-English translation table and is an array of pointers to data type int.

int *p[];
     ^
c

Here the Identifier is p and is simply intepreted as “p is”.

Step 2 – Read all symbols to the right#

Next, continue with symbols on the right of the Identifier until there is no symbol remaining OR encountering a right parenthesis.

From the Symbol-English table, the ”[]” appended after the Identifier is interpreted as “Identifier is array of” or in the case of ”()” is “Identifier is function returning”.

int *p[];
      ^^
c

Here the squared bracket is [] encountered and can be intepreted as “p is array of”.

A special case of multiple left parenthesis with nesting between the initial parentheses only means that the whole procedure is repeated.

Step 3 – Read all symbols to the left and then the data type#

Once there is no symbol on the right, moving towards the data type starting at the Identifier, i.e. left direction, until there is no symbol remaining OR encountering a left parenthesis.

int *p[];
    ^
c

Here the asterisk is * encountered and can be intepreted as “p is array of pointer to”.

Lastly, if there is no symbol belong to the Symbol-English table left, evaluate the data type.

int *p[];
^^^
c

Here the data type is int encountered and can be intepreted as “p is array of pointer to int”.

Nested Declaration#

Now using int *(*func())(); for declaration to address the nesting as previously mentioned.

// Step 1 - Find the Identifier
int *(*func())();
       ^^^^
// "func is"

// Step 2 - Read all symbols to the right
int *(*func())();
           ^^
// "func is" 
// found "()", appending "function returning"

// Step 3 - Encounter right parenthesis, 
// read all symbols to the left
int *(*func())();
      ^
// "func is function returning" 
// found "*", appending "pointer to"

// Step 4 - Encounter left parenthesis, 
// return to read all symbols to the right
int *(*func())();
              ^^
// "func is function returning pointer to"
// found "()", appending "function returning"

// Step 5 - No remaining symbols on the right, 
// return to read all symbols to the left
int *(*func())();
    ^
// "func is function returning pointer to function returning"
// found "*", appending "pointer to"

// Step 6 - Finally, no remaining symbols on either sides, 
// evaluate data type
int *(*func())();
^^^
// "func is function returning pointer to function returning pointer to"
// found data type, appending "int".
c

The final result is “func is function returning pointer to function returning pointer to int”.

Illegal Declaration#

Although not required upto this, knowledge of legal C declaration is necessary to avoid making illegal declaration eventhough they made sense in English-like interpretation.

PairsIllegal combinationsCorrect intepretation
[ ]( )an array of functionsan array of pointers to functions
( )( )a function returns a functiona function returns a pointer to a function
( )[ ]a function returns an arraya function returns a pointer to an array

Interprete English-like declaration also required to make proper and valid declaration based on the C programming syntax

Take the first example from this article, strip down argument list and array size, and modify it as int *((*func_ptr)())[][];. Now this is interpreted as

func_ptr is pointer to function returning array of array of
                       ^^^^^^^^^^^^^^^^^^^^^^^^
pointer to int
c

This will cause error thrown despite made sense following the Right-Left rule, because technically a function cannot return an array, but rather the pointer to that array.

Acknowledgement#

This tutorial is heavily influenced by Lecture Notes created by Mr. Rick Ord from the Computer Science and Engineering Department, UC San Diego in California, USA.

Intuitive Understanding of C Declaration
https://tin.ng/blog/2020-02-06--intuitive-understanding-of-c-declaration
Author Tin Nguyen
Published at February 6, 2020
Comment seems to stuck. Try to refresh?✨