What do you find so disagreeable about collecting variables at the top of a function? For the most part, I like having all the variable declarations at the top, so it's easy to see what names are in what scope.
Finally got the silly regex. To align poor_style in vim with the tabularize plugin:
:Tab /\S\s\zs[ ]\S*
Explanation: \S\s* finds a non whitespace character followed by as many whitespace characters as possible. This brings us to the beginning of the variable name. We then use \zs which says that the "found" area should only begin here.
Since we want the * in block_style to be attached to the indented word but not before the variable name, we match either * or space followed by a non-whitespace character to symbolize the beginning of the word. End result:
Regarding poor_style(), I've never understood this objection (and indeed I prefer the block style you complain about there). Can't your editor fix this up for you in a few keystrokes? This is the sort of thing that an editor should make easy.
1. It wastes my time. Sure, I could probably set up my editor to fix this, but I shouldn't have to do so to satisfy someone else's pointless indentation fetish. I've personally never worked on a team where this was an accepted, general guideline. It was always just one guy who wanted this, and did it to every function he touched, adding maintenance headaches for everyone else (until/unless other people finally told him to stop).
2. It messes up diffs. Now instead of one line showing up in the diff, the entire block is often different. And yes, most diff tools have options to hide whitespace differences. Again, though, this adds overhead to everyone who doesn't want this block style. I'd rather not hide whitespace differences, because if someone has added a bunch of inappropriate whitespace (or mangled the block while trying to reformat it to include their new variable), I want to know about it during the code review so I can tell them to fix it then rather than finding it later when I'm editing the file.
3. It doesn't actually help anything. Yes, you get a nice column that shows you all the variable names. What good is that, though? Unless you're putting everything at the top of the function (which has its own set of problems), you're not really getting anything useful from this except maybe prettier code (arguable), because at a glance you still don't really get know all the in-scope variables (not to mention file-scope variables). Moreover, you actually lose something valuable with this style, because now it's harder to determine a variable's type. You're trying to scan left from the name across some indeterminate amount of whitespace to match with the type. This is not typically easy to do, which is why column-oriented data is typically displayed with alternating background colors on each row.
I bet that some programmers' brains need those orderly columns in order to be able to parse the code effectively, overwhelmed by the chaos of rivers of whitespace otherwise. In that case, it sounds like an editor that displays in columns but stores in compact form would be helpful.
Your up fornt example isn't a result of poor style it's the result of a bad programmer. Assigning the right values to the right variables is the most basic of programming concepts. Sure typo's and bugs happen, I've done it too but it's still a programmer error not style error.
Any style that encourages errors is a bad style. Yes, it's possible to make the code correct and still use up-front declarations. It's also possible to make the code correct while using a 10k-line main() littered with gotos. It's still a very poor programming style.
People make mistakes. Practices should be built around this fact, not built assuming people could be perfect if they just tried a little harder.
Yes. I have absolutely seen bugs caused by the wrong variables being assigned to. I've seen it especially with loop variables. jaegerpicker indicates that he's also caused bugs by assigning to the wrong variables.
Not sure what you mean about "heavy constructor/destructor use" requiring this style.
If your function is five pages long, and in the fifth page you can't remember what's in scope and you have to reread through the entire function above, it might seem that having all variable declarations at the top would help, because you'd only have one place to look at. But the real problem there is that the function is too long, and it should be refactored instead.
Declaring at the top of a function conflicts with the C++ convention of powerful constructors. It's perfectly normal for a C++ class to allocate a lot of memory, open a network socket, or do any other number of heavy-weight things during construction. If you declare all variables at the top of the function, you're forced to have C-style init functions for all data structures that you call separately.
I was reading '21st Century C' (I strongly recommend it for anyone writing C on a regular basis), and the author also argued against declaring all the variables up front. I don't quite know why, but I had a very strong reaction against it. As far as best practices go, I would try to keep every function small enough that you can find all the stack variables easily. If the function gets too hairy, refactor it so you can follow where the variables are going.
You can't do that unless you look at the assembly output. While there may have once been a time in history where "locally-scoped variable == entry on stack", those days are long gone. Any decently smart compiler (i.e. GCC and LLVM) will use registers in preference to the stack, and will collapse local variables whose lifetimes do not overlap into a single storage location.
My bad, I meant locally scoped, I tend to think in terms of "it's on the stack (or a register), or it's on the heap (because it's been malloc'd and needs to be freed)". I do need to review my terminology...
The only time you actually need to declare variables up front nowadays is if you have a goto that would otherwise skip over stack-allocated variable declarations. It's only a problem on certain compilers, but there are enough of them that it's best to keep variable declarations up front in such cases.
I don't see any advantages of declaring variables up front. Not all variables should be at the function scope. Often I have a local variable that is only used inside one branch of a conditional, why should I declare that at the top? Declaring things up front also separates the type from the usage, which makes things harder to read and takes up twice as many lines in some cases.
Maybe I miscommunicated; I'm not against declaring variables at scopes smaller than the function - I declare variables at the top of conditional branches as well. I still don't buy the 'twice as many lines' reason for mixing assignment and declaration.
It makes it difficult to have const locals if you get some sort of dependency chain based on other locals interspersed with other computation. For example, if you're a const nazi you can't have code like this:
const int x = foo();
const int y = bar(x);
and also have your variables all declared at the top.
In C++ I'm a const nazi and declare where used to facilitate it, but if I'm writing C that targets the MSVC compiler (C89) where all variables have to be collected at the top of the inner scope I'll relax this as much as I have to.
Among other things already mentioned, it makes it impossible to be "const pedantic" as Mr. Carmack professes to now be, i.e. declaring everything that is only initialized and then never changed as const.
I most certainly am const pedantic as well, and I was back when I worked on this project, too -- quite a few of the "inconsequential" lines I checked in were simply moving a variable declaration down to where it was initialized, and adding 'const'. I found the resulting code much easier to read.