Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's not (unless you mean "by popular convention", which actually is not necessarily that popular).

int* c is perfectly valid syntax

and so is int * c.

The latter is my preferred convention: it helps me think of the asterisk as an operator, which, when acting at the "declaration" level, is binary in nature.

Whereas when the asterisk is used at the 'expression' level, it is unary in nature, and can be thought of effectively as a completely different operator that happens to share the same name/symbol as the declaration-based one.



I'd advise not doing "int* c" as it is misleading. Consider

int* a, b;

This looks as though it is equivalent to

int* a;

int* b;

but actually means

int* a;

int b;

Most people trying it your way hit this issue fairly quickly and revert to "int *a". It's not just a meaningless convention; it's a convention which reflects the grammar of the language just as conventions on indentation reflect it.

"int * a" is not as bad, in that it is ambiguous rather than misleading, but I would avoid it for similar reasons.*


Fair enough. Though, to some extent, one could counter this by pointing out that multiple declarations via the comma type-operator are generally considered ambiguous / bad practice in themselves; in which case I would prefer explicit spacing to discourage such bad habits. Otherwise, ideally the asterisk should be grouped anyway (i.e. int (* a), b; ).

Besides, a similar argument could be made of simultaneous array declarations, or things like int *f(), (*g)(); in the latter example, if I were lazy enough to use such a simultaneous declaration, at least I would still prefer to use proper grouping and spacing: int (* f()), (* g)();

Or, rely on the knowledge that the comma type-operator in this context binds less strongly than the asterisk type-operator, but more strongly than the type primitive, which causes it to be distributed to all the operands of the comma operator. Which is probably better than relying on proximity-by-convention heuristics in the first place.


The comma operator does exist, of course, but I've never heard of the comma in the context of C variable declarations being described as an operator, nor does a web search on "comma type operator" return any results. It doesn't behave like an operator (it does not return a result). You might argue that in some sense it "returns a type", but this is C: types are not objects in the language, and in any case the preceding declaration would also be held to "return a type". No, it's just a separator in C.

Yes, some people recommend one declaration per line. It's generally a defensive habit, needed if you use spacing which doesn't reflect the grammar of the language. It's the C programming equivalent of double-knotting shoe-laces to stop them coming undone rather than recognising that the bow has been tied with a granny knot rather than a reef knot.

I do concede that if I had multiple complex declarations like int *f(), (*g)(); I would separate them on to different lines, but there is no need for that with easily read declarations such as int *a, b;.


Yes you're right; in retrospect I should have used quotes around the phrase "type-operator" or something, this is entirely my wording. And also I'm using 'operator' here loosely, to mean an operation conducted via a symbol and some 'operands', which are not necessarily expressions, or expected to return another expression. (casting works a similar way, for instance, in that it is typically talked of as an operator, but one of the operands is a type rather than an expression, and it's debatable whether the operation actually 'returns' something or simply causes a particular type-interpretation as a side-effect).

So effectively I like to think of all symbols in a declaration statement as "operators" in some broader sense. As you say, you could think of this as "returning a type", semantically speaking, though I think more usefully I would talk about the operator as having the particular operational side-effect of allocating the correct kind of memory for that object, as per the declared type. Of course I realise that the language doesn't formally define these symbols as 'operators acting in a declaration context' as such in the standard; but, equally, the actual wording doesn't prevent you from viewing these symbols in such an operational manner either. And I find thinking of them as operators in this manner to be more informative and predictive than the super-reductive "it's just what the syntax is", which could be applied to any part of the language, reducing all discussion about semantics to nothing.

And "comma type-operator" because, well, inevitably if I just call it "comma operator", even if I'm explicitly pointing out the fact that I'm talking about the declaration rather than the expression context, someone will miss the point anyway and fixate on the fact that "this is not the comma operator" (which would be technically correct but totally not the point); therefore I take some creative liberties and refer to it as a "type-operator", in that it only carries these semantics in a declaration context :)

Regarding the granny knot analogy, I agree, but at the same time you could argue that complexity is a matter of perspective, and therefore one could argue similarly that you might as well disambiguate int * a by treating it as an operator (semantically speaking) and thus spacing it properly, and putting each declaration on a single line, as opposed to oversimplifying syntax by relying on arbitrary proximity conventions, in order to combining a bunch of declarations together; which would be like saying I'm hoping this knot is too simple to be a reef knot, I'm hoping nobody will think it's a reef knot, so no need for a double knot here. :p

In any case, I don't necessarily disagree with placing the asterisk close to the variable, but I consider this mostly a stylistic issue, and stylistically I prefer spacing the two. What I do object to is that this is the one correct way; I think it's prone to interpretation problems as much as the others (the specific issue you pointed out notwithstanding), and one should prefer proper grouping for disambiguation, rather than relying on proximity conventions. So to the extent that spacing things encourages one to provide clearer groupings and keep things in separate lines, leading to more robust code, I would prefer spacing for that reason alone.

(unless my team's style guide forced me to, of course. I'm not going on a holy war over this, it's just my preferred style/philosophy :D )

(sorry for the long reply, I'm bored in a cafe and procrastinating from actual work. thanks for the discussion and food for thought!)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: