The guidelines do state that variables should be declared as locally as possible, so variables declared inside for loops, do/while blocks, case blocks, etc. are encouraged.
The big flaw in not using braces has been pointed out, so I agree that case statements should have braces exactly for the purpose of declaring variables locally to assist in refactoring.
Guidelines are, after all, guidelines... there comes a point where you need to ignore them so that you code is more readable (string constants going over 80 columns for example). I have no issue with parameter asserts being at the very start of the function, particularly when you want to do the this:
which is cleaner and shorter than this:
I also don't mind them being immediately after variable declarations
Typically we refactor blocks of code, like functionising the internals of a loop. The local variables will be declared at the start of that block of code and should come out nice and cleanly.
I, personally, find it very messy when there are variable declarations spread semi-randomly through the code. I find my train of though works better when I know upfront what types of data the following code will be dealing with - like
"OK, this block of code will be messing around with a foo - I haven't seen a foo for a while, I'll quickly check foo.h - yep, got it. Now let's look at the code"
Versus
"OK yep, yep, got it, um, bugger, what's a foo look like, better check foo.h. Right, got it, now, what was this code doing, bugger, better go back to the start"
That would be multi-assignments and double blanks
For case statements I don't see a problem with them sometimes having braces and sometimes not, depending on whether variables are declared there, and if there are variables, it's easier to refactor later (e.g. by splitting the contents of the case statement to another function).
For mixed declarations and code, I guess I've never had any problem finding variables in a function, but I've repeatedly had situations where I've done something like:
when it would have been much neater to start the function with asserts and then make the declaration of x and its value assignment on the same line.
Code:
int x; assert(y != NULL); x = y->property;
Code:
int my_function(struct object *obj) { assert(obj); int x = obj->x; int y = obj->y; }
Code:
int my_function(struct object *obj) { int x, y; assert(obj); x = obj->x; y = obj->y; }
And If anything, I think putting variable declarations at the latest possible point for them makes the code less error-prone and easier to refactor, since the stuff you want to refactor is all grouped together.
I, personally, find it very messy when there are variable declarations spread semi-randomly through the code. I find my train of though works better when I know upfront what types of data the following code will be dealing with - like
"OK, this block of code will be messing around with a foo - I haven't seen a foo for a while, I'll quickly check foo.h - yep, got it. Now let's look at the code"
Versus
"OK yep, yep, got it, um, bugger, what's a foo look like, better check foo.h. Right, got it, now, what was this code doing, bugger, better go back to the start"
The rest, I'm easy about, and I can see your points.
Comment