Variables are in scope in their own initializers. This is fun when you inadvertently write something like:
int length = ...;
...more code, lose your concentration...
if(x) {
int length = length / 2 + 1;
...
}
This neither produces an error nor does what you'd expect, but just ends up being a creative way to initialize the inner length variable with garbage. I've done this more than I care to admit.
Definitely. Know your warning options! Also, try using multiple compilers. tcc compiles very quickly, clang often has better error messages, etc.
Speaking of variable shadowing: It's usually worth wrapping any preprocessor macros in a "do { ... } while (0)" block unless you deliberately want variable definitions to escape (in which case, token pasting a suffix is usually a good idea).
That is a gcc extension. The construct as a whole has the value of the last statement executed within. Usually an inline function is preferable since it achieves the same thing using only standard syntax.
Would be nice if there was one which would warn for this specific case but not shadowing in general, which I occasionally like. (This probably makes me a bad person.)
It certainly doesn't make you a bad person. If lexical scoping wasn't the intent of the language authors, it wouldn't exist. I tend to agree that the warning is more of a hassle than it's worth. Though I guess it can be argued that if your scoping is so deep that you actually need to reuse names, that perhaps some refactoring should be in order.
Seeing a variable shadow something in an outer scope makes me cringe, simply because the decrease in readability far outweighs any benefit it could give. You might remember how things are, but the poor sap who has to keep extra scoping depths in his mind just to maintain your code will curse your name every day.