3 ms·
Yup. I spent a ton of time trying to make sense of pointer syntax (* operator/modifier), until I realized that it didn't really make sense (except for the simpl
by young_unixer 6y ago
Yup. I spent a ton of time trying to make sense of pointer syntax (* operator/modifier), until I realized that it didn't really make sense (except for the simplest cases) and then I could get on my life.
- cassepipe 6y agoThere's actually a logic to it, although not an intuitive one at all, and it's that declaration should follow use. That is `int *ptr;` is a pointer to an int and to get the int you have to use * on it.
- jstimpfle 6y agoThe logic is that by declaring `int *ptr;` you effectively say that `*ptr` is an `int`. Only the first token (which must be a type) is syntactically special, the rest is normal expression syntax. Same goes for arrays, `int *x[30]` just says that `*x[30]` is an `int` (well, technically it's out of bounds by 1), thereby we're declaring an array of 30 int-pointers. Of course, that hasn't been entirely true since function declaration changed with ANSI C in the late 80s or so.
- kaba0 6y agoBut int-pointer is the type of it. It makes no sense that it “sticks” to the variable name.
- Koshkin 6y agoThe reason the asterisk naturally "sticks to" the name is simply the possibility to write a series of declarations like this: int a, *b, (*c)(int);
- kaba0 6y agoWhich is a questionable saving of 2 lines and a few characters in a language where huge repetitions are a given, due to lack of templates/generics whatever.
- deleted 6y ago[deleted]
- bluetomcat 6y agoThere's a type and an identifier. In `int *pa[10]`, the identifier is `pa` and the type is `int *[10]`. A declaration simply specifies a name (the identifier), some operations around it (pointer dereferencing, array subscription, function calling, grouping parentheses) and the terminal type that you get after applying all those operators in the precise order as specified by operator precedence rules. When using that variable with the allowed operators, the resultant type of the expression is determined by the declaration: pa; // int *[10] pa[x]; // int * *pa[x]; // int
- kaba0 6y agoThank you for the concise write up, but I think lowly of the [] syntax as well. And unary operators on an identifier are a different thing, though I similarly don’t think adding one at the left, another at the right is a good thing. But I have trouble with the declaration site as well. It’s getting out of reach of my knowledge, but I believe C’s grammar being hacky is in part due to that as well. I didn’t find exactly what I was looking for but here is some more on it: https://pdos.csail.mit.edu/archive/l/c/roskind.html https://pdos.csail.mit.edu/archive/l/c/roskind.html
- cassepipe 6y agoYou missed the whole point. Yes, it makes no sense until you grok the logic of it and then it starts making sense (while still being unintuitive). Re-read the comments you are responding to.
- kaba0 6y agoYeah I get that it has logic (though by being pedantic, anything we can write a parser for has logic, but I’m sure we could create some stupid languages), but as you yourself note, not very intuitive. And as far as I know, it doesn’t ease the work of parser-writers.
- kevin_thibedeau 6y agoint * a, b; Here it sticks to a. Then typedef comes along and ruins everything: typedef int * pint; pint c, d;