5 ms·
Scanning through the list of features, one I dislike is selection statement initializers: if (init; condition) {} (Ref: http://www.open-std.org/jtc1/sc22/wg21
by tcbawo 9y ago
Scanning through the list of features, one I dislike is selection statement initializers:
if (init; condition) {}
(Ref: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p030...). It just seems like clutter. I generally prefer when languages discourage side effects in a branch condition.
- BudVVeezer 9y agoIt's consistent with for (init; condition;) {} and solves a problem like: if (std::vector<int> v = f(); !v.empty()) { // Use v } without requiring an extra compound statement to limit the scope and lifetime of v.
- tcbawo 9y agoI agree that it's consistent, I find it easier to read when the branching condition is front and center. In 99% of cases I've encountered, the scope of the branching condition variable doesn't matter. When it does, an extra set of {} defines a scope clearly.
- leni536 9y agoAn extra set of {} seems to be clutter to me.
- lomnakkus 9y agoThat plus extra indentation. It also obscures the intent since it's not necessarily unambiguous why those braces are there? Is it just to group logically related code (without putting it in a separate method/function) or is it because you're relying on RAII -- it's only possible to tell by searching for destructors on all the classes you're instantiating.
- jacobparker 9y agoThat's sorta the point... the init isn't the branch condition. It gives terser syntax to a common patter where you want to scope something into the body of an if statement. { std::unique_ptr<T> x = foo(); if(x->something()) { // use x } } // x out of scope, destructed becomes if(auto x = foo(); x->something()) { // use x } // x out of scope, destructed It's makes it easier to read the lifetime of x (an important thing you have to manually keep an eye on in C++ in many cases), and to determine what is in scope outside of the if statement. It's analogous to for-loops vs. doing loops "manually" with while. You're just used to for-loops by this point (if you don't like for loops then ok :).) C# is also getting (has got?) this feature.
- tcbawo 9y agoIf I'm reading the paper right, the init statement could be any expression-statement or simple initialization. So, modifying unrelated, externally scoped variables in the init would be legal. I don't see this improving readability.
- roel_v 9y agoWell, "#define if while" is also legal, and doesn't improve readability either. Like most features, when abused, they're a liability.
- rleigh 9y agoIt's no different than the init and conditional parts of a for loop. Do people abuse for loops to do unrelated tasks? Not really. It does improve readability. If you've ever had to have a series of conditionals in their own braces to keep the init variable in its own scope, then you have a use for this. The alternative might be having foo1, foo2, foo3… all in the same scope, and it's too easy to use the wrong one. This keeps things specifically constrained to the scope in which they are used, which improves safety and correctness, and I think also readability once you adapt to it. Yes, it could be abused, but I don't think that's a reason not to use it for its intended purpose.
- 9y ago