3 ms·
My take on this: pro: - Storage concerns are separated and grouped at the top. - Logic code is more compact, helping readability. - Stack use can be determi
by yvdriess 6y ago
My take on this:
pro:
- Storage concerns are separated and grouped at the top.
- Logic code is more compact, helping readability.
- Stack use can be determined at a glance.
- Looking up a variable's type is faster in cases where a variable is used throughout the code block. This is good to optimize, as you constantly need to look up variables when reading C code.
- Reflects that object lifetime of any stack storage object is the same regardless of where it is declared in the code block.
cons:
- For long functions, the distance between use an declaration lines can impair looking up a var's type. (having to scroll to get to the top of your function is a sign you need to break it up though)
- In many cases, a variable is only used in one location in the block and has a meaningful static initialization. Local declarations in this case readability, as it does not have to be looked up.
- "-Wuninitialized" exists, but passing pointer and defining 'default' value style can still cause read-before-write.
I tend to an in-between style, where code is grouped where it makes sense with group-local variables declared in front. Variables that are used throughout the entire code block body are declared at the very top.
- MaxBarraclough 6y ago> Storage concerns are separated and grouped at the top. That's rather circular. That's what defines the style, it's not in itself an advantage or a disadvantage. > Logic code is more compact, helping readability It's slightly more compact, but it harms readability, as I describe at [0]. Using the new style, especially with the const keyword, can make code much more readable. > Stack use can be determined at a glance. It can't, that's up to the compiler. Perhaps all locals will be enregistered. Even if it were true, it's extremely rare to need to do this. > Looking up a variable's type is faster in cases where a variable is used throughout the code block. In certain circumstances this may be true, but there may still be multiple levels you may have to check. For short-lived locals, it will be quicker to look up the type using the new style, as that keeps the declaration close to where it is used. Using a modern IDE, it's a draw - just hover over a local and it will tell you its type. > Reflects that object lifetime of any stack storage object is the same regardless of where it is declared in the code block. That doesn't sound right. That will be platform-dependent. I see no reason a compiler couldn't generate incremental pushes, rather than an upfront block allocation. Also, depending on what the compiler generates, different locals may end up occupying the same place in the stack (at different times), and a given local may be held in different places in the stack at different times. And that's if we're ignoring registers. No matter what we do, we can't rely on the generated assembly looking anything like the source code. Beyond that, it's 'dishonest' about locals' real lifetimes, in a way that can be harmful. Compare: { // Old style int i; int j; i = j; // Undefined behaviour j = 7; } { // New style int i = j; // Compile-time error. 'j' is not in scope. int j = 7; } > "-Wuninitialized" exists, but passing pointer and defining 'default' value style can still cause read-before-write. I'm afraid I don't get what you're saying here. Are you referring to the danger of passing a 'default' value to a function, say, in a way that might be dangerous?