Live data from Hacker News

The Clockwise/Spiral Rule of C declarations

c-faq.com

41–50 of 72 posts

Re: The Clockwise/Spiral Rule of C declarations

#41
symbols with equal amount of open and close parentheses in order are counted by Catalan numbers

    (())()(()())(())
these count different arrangement of parentheses for function application. this guy is describing something like contour integration for computer programs

Re: The Clockwise/Spiral Rule of C declarations

#43
What is the value of bending ourselves to fit a confusingly designed old language, rather than bending the language to fit us? The very fact that articles like this have to be written indicates a failure of user interface design, which we needn't forever perpetuate.

Re: The Clockwise/Spiral Rule of C declarations

#44

Way simpler: from inside out, read any subpart of the type as an expression. (Arrays have precedence over pointers, as usual.) The type that remains is that expression's type. So e.g. given the type: const char *foo[][50] the following expressions have the following types: foo -> const char *[][50] foo[0] -> const char * [50] foo[0][0] -> const char * *foo[0][0] -> const char Another example: int (*const bar)[restric…

What happened to the const in the second example?

That const applies only to the bar symbol itself, not to anything it points to. So once bar is dereferenced, the const doesn't matter. The beauty of this method is that it predicts that correctly without having to think about it.

Re: The Clockwise/Spiral Rule of C declarations

#45
post #22

Earlier quoted context omitted.

What happened to the const in the second example?

Yeah, I think they confused const * with * const

Nope, * const means that the identifier (i.e. thing to the right of the star) is const. That is, in this example, the symbol "bar" is const, not anything that it points to. So once you dereference it, the const no longer matters.

Re: The Clockwise/Spiral Rule of C declarations

#46
post #15

Just don't make complex declarations in C, it's almost never useful and won't help anyone out. It'll confuse people and make your code write-only. Just put in a couple extra lines of code somewhere if you have to. It won't be the end of the world.

It'll certainly confuse people, but only those who aren't qualified to be doing anything with the code anyway. "complex" is subjective. It reminds me of stupid "rules" like "don't use the ternary operator", "every function must be less than 20 lines" (I am not exaggerating --- this was on a Java project, however); and you could easily extend that to "every statement must have a maximum of one operator", "you must not…

It'll certainly confuse people, but only those who aren't qualified to be doing anything with the code anyway.

And people wonder why there are so many broken C programs out there...

Re: The Clockwise/Spiral Rule of C declarations

#47
post #15

Just don't make complex declarations in C, it's almost never useful and won't help anyone out. It'll confuse people and make your code write-only. Just put in a couple extra lines of code somewhere if you have to. It won't be the end of the world.

It'll certainly confuse people, but only those who aren't qualified to be doing anything with the code anyway. "complex" is subjective. It reminds me of stupid "rules" like "don't use the ternary operator", "every function must be less than 20 lines" (I am not exaggerating --- this was on a Java project, however); and you could easily extend that to "every statement must have a maximum of one operator", "you must not…

>> It'll certainly confuse people, but only those who aren't qualified to be doing anything with the code anyway.

If the complexity can be avoided, why not avoid it. Removing complexity is not the same as dumb-downing code. It will improve readability and maintainability.

This mindset is defintitely applicable to declaration as well as code construct.

edit: clarity.

Re: The Clockwise/Spiral Rule of C declarations

#48
post #5

What makes me wonder is why C ended up with such a syntax. That is, its contemporary, Pascal, has a very straightforward, unambiguous syntax.

The type syntax exactly matches the expression syntax used to destruct values of the type. It is very intuitive once you realize this. The alternative would be for the type syntax to mirror the expression syntax used to construct values of the type. Functional languages tend to do this, particularly ones which prefer pattern matching over destructors.

Yeah, the rule is intuitive when I am writing the code, but I think the type declarations in other languages like Go are easier to read correctly when I am skimming through the code even though I am much more used to C. I am not sure how useful this mirroring of usage is in practice.

Re: The Clockwise/Spiral Rule of C declarations

#49

Earlier quoted context omitted.

I am not familiar with Go, and have heard many praises of its declaration syntax, but is its dereference operator postfix? That would make sense in such a case. On the other hand, IMHO the whole "make declarations read left-to-right" idea is misguided --- plenty of other constructs exist in programming languages which simply can't be read left-to-right, but are nested according to precedence. I mean, you might as wel…

Go's defererence operator `*` is prefix, like in C. The point here is that type declarations are regular to read, and those tend to be the tricky ones. Expressions tend not to be so difficult, and are more commonly factored if they become complex. For various reason, type declarations are not so practically factorable.

When I came to Go, I hadn't used C or C++ for over a decade, only Java and C# in between. Using explicitly written pointers came flooding back, but the new "C for expressions, Pascal for declarations" syntax still takes getting used to.

Declaring `v * T` means we can write `* v` as an expression, so the use of token * is synchronized for both these uses, but I must vocalize the * in my head differently:

  `*T` vocalizes as "pointer to something of type T"
  `*v` vocalizes as "that pointed to by variable v"
  `&v` vocalizes as "pointer to variable v"
So my thought process when I see * goes: If it's in a type, say "pointer to", otherwise say the opposite of "pointer to", i.e. "that pointed to by". It feels like an inconsistent use of * whenever I'm writing Go code -- even though I know it's a natural result of Go using Pascal-style declaration syntax but C-style tokens.

Re: The Clockwise/Spiral Rule of C declarations

#50
post #22

Earlier quoted context omitted.

Yeah, I think they confused const * with * const

Nope, * const means that the identifier (i.e. thing to the right of the star) is const. That is, in this example, the symbol "bar" is const, not anything that it points to. So once you dereference it, the const no longer matters.

You're right, I got confused. const is read as "the thing to the right of me is const". const * means const pointer, * const means pointer to const.
Post reply on HN