I'm very much not a C programmer, but I've never understood why it seems far more common to write `float *foo` instead of `float* foo`. The "pointerness" is part of the type and to me the latter expresses that far more clearly.
On the other hand, for those of us who agree with the GP on this, one way around the pitfall is to have your project's style guide ban multiple declarations on a single line, or at least ban them for non-trivial variables— so `int x, y, z;` is permitted, but nothing more than that.
Because it isn't - `float* foo, bar;` foo is a pointer, bar is not.
(There were suggestions back in the 90s that to make C easier to parse for humans (and not-coincidentally simplify the compiler grammar) this should be `foo, bar: float*;` and your model of pointerness could actually be true. Never got much more traction than some "huh, that would be better, too bad we've been using this for 10 years already and will never change it" comments :-) (with an occasional side of "maybe use typedefs instead")
Good news (kinda): C23 allows (and GCC has for a long long time allowed) you to write typeof(float *) foo, bar; and declare two pointers. Not that I’d advocate writing normal declarations that way, but at least now you can write macros (e.g. for allocation) that don’t choke on arbitrary type names.
It's either that, or making a pointer type to bind things correctly. Convention is there to paper over shitty, shitty behavior in the language that is easy to trip yourself up on.
I think it is a manner of preference, both "float* foo" and "float *foo" are widely used.
Personally i used "float *foo" for years until at some point i found "float* foo" more natural (as the pointer is conceptually part of the type) so i switched to that, which i've also been using for years. I've worked on a bunch of codebases which used both though (both in C and C++) - in some cases even mixed because that's what you get with a codebase where a ton of programmers worked over many years :-P.
I do tend to put pointer variable declarations on their own lines though regardless of asterisk placement.
(and of course there is always "float foo[42]" to annoy you with the whole "part of the type" aspect :-P)*
For the same reason you don’t write x+y * z: because then the spacing contradicts the way the priorities work in the language.
We might wish for the C declaration syntax to be <type> <name>[, ...], but it’s not: it’s <specifier>[ ...] <declarator>[, ...], where int, long, unsigned, struct stat, union { uint64_t u; double d; }, and even typedef are all specifiers, and foo, (foo), (((foo))), *bar, baz[10], (*spam)(int), and even (*eggs)[STRIDE] are all declarators (the wisdom of using the last one is debatable, but it is genuinely useful if you can count on the future maintainer to know what it means).
Everybody is free to not like the syntax, but actively misleading the reader about its workings seems counterproductive.
I swear if I see one more "int* x, y" example I will flip a keyboard. This isn't the 90s anymore. Everyone and their mother knows about this one pitfall, repeated for decades by people who have yet to read the memo that we now declare one variable per line, so it is never an issue. Even if you make this mistake, it's the least of your worries when coding in C because the compiler will typically warn you when you try to use the integer as a pointer.
Get with the program: types on the left, names on the right, one declaration per line.