How do you read the C declarations?

I heard about some methods, but none of them got stuck. Personally, I try to avoid complex types in C and try to break them down into a typedef component.

Now I am faced with saving some inherited code from the so-called "three-star programmer", and it’s hard for me to read some of the *** code [] [].

How do you read complex C declarations?

+41
c typedef cdecl
Sep 18 '08 at 0:57
source share
12 answers

This article explains the relatively simple 7 rules that will let you read any C declaration if you want or want to do it manually: http://www.ericgiguere.com/articles/reading-c-declarations.html

  • Find the identifier. This is your starting point. On the piece of paper write "declare identifier as."
  • Look to the right. If there is nothing there or the correct bracket is “)”, go to step 4.
  • Now you are either on the array descriptor (left bracket) or on the function (left bracket). There may be a sequence of them ending either with an inconsistent right bracket or with the end of the declarator (semicolon or "=" to initialize). For each such descriptor reading from left to right:

    • if the empty array is "[]", write "array"
    • If the array is with size, write "array size"
    • if the function is (), write "return function"

    Stop in an inconsistent bracket or at the end of the announcement, whichever comes first.

  • Return to starting position and look to the left. If there is nothing there or there is a left bracket "(", goto step 6.
  • You are now on the handle to the "*" pointer. There may be a sequence of them to the left, ending either with the unsurpassed left bracket “(” or the beginning of the declarator. Reading from right to left, for each pointer of the descriptor write “pointer to.” Stop in the inconsistent bracket or the beginning of the declarator, whichever comes first .
  • At this point, you have either an expression in brackets or a full declarator. If you have an expression in parentheses, consider it as a new starting point and return to step 2.
  • Record the type specifier. Stop.

If you have everything in order with the tool, then I suggest using the cdecl program: http://gd.tuwien.ac.at/linuxcommand.org/man_pages/cdecl1.html

+27
Sep 18 '08 at 1:07
source share

I usually use what is sometimes called the "clockwise right rule." This happens as follows:

  • Start with the id.
  • Go straight to him.
  • Then move clockwise and go left.
  • Move clockwise and go to the right.
  • Do this until the declaration has been fully analyzed.

There is an additional meta rule to take care of:

  • If there are parentheses, complete each level of parentheses before moving.

Here, “movement” and “movement” somewhere means reading a character. Rules for this:

  • * - pointer to
  • () - return function
  • (int, int) - a function that takes two ints and returns
  • int , char , etc. - int , char , etc.
  • [] - array
  • [10] - an array of ten
  • and etc.

So, for example, int* (*xyz[10])(int*, char) reads like:

xyz is

array of ten

pointer to

taking int * and a char and returning

a int *

+20
Sep 18 '08 at 7:14
source share

One word: cdecl

Damn beaten for 15 seconds!

+5
Sep 18 '08 at 1:02
source share
+5
Sep 19 '08 at 19:09
source share

Cdecl (and C ++ decl) is a program for encoding and decoding declarations of type C (or C ++).

http://gd.tuwien.ac.at/linuxcommand.org/man_pages/cdecl1.html

+4
Sep 18 '08 at 1:03
source share

When I did C, I used a program called "cdecl". This seems to be on Ubuntu Linux in the cutils or cdecl package, and it is probably available elsewhere.

+3
Sep 18 '08 at 1:01
source share

cdecl offers a command line interface, so give it a try:

 cdecl> explain int ***c[][] declare c as array of array of pointer to pointer to pointer to int 

another example

  explain int (*IMP)(ID,SEL) declare IMP as pointer to function (ID, SEL) returning int 

However, there is a whole chapter about this in C Deep Secrets, entitled Unscrambling declarations in C.

Relations Friedrich

+1
Sep 18 '08 at 6:41
source share

There is also a web version of cdecl , which is pretty smooth.

+1
May 27 '11 at 4:15 a.m.
source share

Common readability issues include pointers to functions and the fact that arrays are really pointers and that multidimensional arrays are really one-dimensional arrays (which are really pointers). Hope this helps.

In any case, whenever you understand the declarations, perhaps you can find a way to simplify them to make them more readable for the next guy.

0
Sep 18 '08 at 1:04
source share

The automatic solution is cdecl.

In general, you declare a variable the way you use it. For example, you are looking for a pointer p like:

 char c = * p

you state it in the same way:

 char * p;

The same goes for hairy function pointers. Let f declare a good old "function pointer returning a pointer to int" and the external declaration is just ridiculous. This is a function pointer, so we start with:

 extern * f ();

It returns a pointer to int, so somewhere there

 extern int * * f ();  // XXX not quite yet

Now, what is the correct associativity? I never remember, so use parentheses.

 extern (int *) (* f) ();

Declare it the way you use it.

0
Sep 20 '08 at 3:48
source share

Read from right to left.

 ***code[][] 
  • code [] [] is a multidimensional array
  • * code [] [] is a multidimensional array pointer
  • ** code [] [] is a multidimensional array pointer to a pointer
  • *** code [] [] is a multidimensional array pointer to a pointer to a pointer
0
Oct 03 '08 at 5:22
source share

I just stumbled upon the illuminating section in the "Development of C Language " section:

For every object of this arranged type, there is already a way to specify a basic object: index the array, call a function, use the pointer operator on the pointer. Similar reasoning led to the declaration syntax for names that reflect the syntax of the expression in which names usually appear. In this way,

int i, *pi, **ppi;

declare an integer, a pointer to an integer, a pointer to a pointer to an integer. The syntax of these declarations reflects the observation that i, * pi and ** ppi all give an int type when used in an expression. Similarly

int f(), *f(), (*f)();

declare a function that returns an integer, a function that returns a pointer to an integer, a pointer to a function that returns an integer;

int *api[10], (*pai)[10];

declare an array of pointers to integers and a pointer to an array of integers. In all these cases, the declaration of a variable resembles its use in an expression whose type is the name indicated at the head of the declaration.

0
Dec 05 '09 at 7:11
source share



All Articles