Back to News
Advertisement
Advertisement

⚡ Community Insights

Discussion Sentiment

100% Positive

Analyzed from 409 words in the discussion.

Trending Topics

#int#array#pointers#pointer#char#whatever#rule#function#typedef#type

Discussion (8 Comments)Read Original on HackerNews

pcfwikabout 1 hour ago
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

nitrix31 minutes ago
Some more examples:

  int v, *w, x[5], *y[5], (*z[5])(int, int);
Where v is an int, w is a pointer, x is an array, y is an array of pointers, z is an array of function pointers, etc.

Similarly, typedef is also just a keyword in front of a regular declaration.

  int foo[5];
  typedef int foo[5];

  int bar(void);
  typedef int bar(void);
Now you can use `bar *` as a function pointer.

The entire language works like this.

stephencanonabout 1 hour ago
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).

mananaysiempreabout 1 hour ago
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[<whatever>]” means that the expression *a[<whatever>] has type char; “char (*a(<whatever>))[<whatever>]” means that the expression (*a(<whatever>))[<whatever>] 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 sufficient. (Hint: all prefix operators have one precedence and all postfix ones another, and you know which one binds tighter if you know what *i++ means.)
jcranmerabout 1 hour ago
The best summary--and easiest to remember, IMHO--is that variables are declared as they are used.

Want to write an array of function pointers that return a pointer to an array of pointers to int? Well, that's:

  array ... -> x[N]
  ... of function pointers ... -> T (*x[N])()
  ... that return a pointer ... -> T *(*x[N])()
  ... to an array ... -> T (*(*x[N])())[M]
  ... of pointers ... -> T *(*(*x[N])())[M]
  ... to int ... -> int *(*(*x[N])())[M]
It doesn't make it all that easy to read, but you can at least write the complex types pretty reliably.

(The real answer is of course to just typedef every function pointer type or pointer-to-array and not worry about it anymore.)

classifiedabout 1 hour ago
This is useful if you're far from the internet. Here's a web site that translates the gibberish to English or vice versa:

https://cdecl.org/

Or

  apt install cdecl
on Linux.
AlienRobotabout 1 hour ago
This is why I like python.

str is a duck.

Joker_vDabout 1 hour ago
> "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...