6 ms·
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 declara
by pcfwik 2mo 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 https://eigenstate.org/notes/c-decl
- nitrix 2mo agoSome 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.
- arjvik 2mo agoThe way I've learned to read it is int v; means that `v` is an `int`. int *w; means that `*w` is an `int`, meaning `w` is a pointer to an `int`. int *y[5] (note that `◌[]` has higher precedence than `*◌`, so this is `*(y[5])`) means that `*y[5]` is an `int`, so `y[5]` is a pointer to an `int`, meaning `y` is an array of `int` pointers. int (*(*kitchensink[5])(int, int))[6]; means that `(*(*kitchensink[5])(int, int))[6]` is an int, so - `*(*kitchensink[5])(int, int)` is an array of `int`. - `(*kitchensink[5])(int, int)` is a pointer to array of `int`. - `kitchensink[5]` is a function pointer to a function that takes `(int, int)` and returns a pointer to an array of `int`. - `kitchensink` is an array of function pointers to functions that take `(int, int)` and return a pointer to an array of `int`.
- kps 2mo ago> int *w; But some misguided style guides demand the misleading `int* w;`, and then act surprised by `int* w, x`;
- tom_ 2mo agoI split the difference and write it "int*w". (Most style guides tell you to declare one name per line anyway...)
- kps 2mo agoI have seen `int * w` in the real world. I'm sad now.
- deleted 2mo ago[deleted]
- uecker 2mo agoThose style guides would also disallow having multiple declarators in a single declaration.
- IronFox05 2mo agoCall me a hater but I don't like the spiral rule and I like "declaration follows use" even less. How do you make an std::array of a given type? Wrap the existing type in an extra layer of std::array, we all know this, it makes sense, there's no reasonable alternative. How do you make a C-array of a given type? Oh boy, "prepend the array specifier before the list of existing array specifiers" (actually it's worse because you have to find the right possibly-empty array of existing array specifiers first, just because there's a list of array specifiers somewhere in the type doesn't mean it's the one you should be prepending to). "Declaration follows use" immediately goes out the window when faced with typedeffed types being used as the base type, or (as mentioned) generics in descendant languages of C. Instead you get "declaration builds up a type by wrapping layers around a core, use breaks down a type layer by layer starting from the outside" (so, necessarily, they mirror each other). C could have worked that way, and it would have made more sense. "Declaration follows use" is the type level equivalent of taking off your socks before taking off your shoes because that's the order in which you put them on.
- jstanley 2mo ago> How do you make an std::array of a given type? std::array isn't a thing in C, so you don't.
- IronFox05 2mo ago[flagged]
- unclad5968 2mo agoJust for future reference, I believe the correct spelling is genius.
- jstanley 2mo agoI can get behind deliberately misspelling as "genious" when using it sarcastically.
- kazinator 2mo agoIf you explain declarations as following use, you are just moving the spiral parse from declarations to expressions. :)
- pcfwik 2mo agoI think this is a valid point. I would much prefer if the spiral rule were presented as a helpful mnemonic for remembering C operator precedence rather than something uniquely connected to declarations!