Initializing variables in an “if” statementC++ IDE for Linux?What are the differences between a pointer variable and a reference variable in C++?Why can't variables be declared in a switch statement?Why use apparently meaningless do-while and if-else statements in macros?Declaring and initializing a variable in a Conditional or Control statement in C++What method do you use to initialize member variables?Best Practice when Declaring and Initializing variables in c++Do users need to fulfill any prerequisites to run C++17 software?C++11 brace/aggregate initialization. When to use it?Performance of recursive Variadic function calls against simple if..else statements
Maximum charterer insertion
Setting MAC field to all-zero to indicate unencrypted data
When casting Eldritch Blast with the Agonizing Blast eldritch invocation, what do I add to my damage roll?
Can fluent English speakers distinguish “steel”, “still” and “steal”?
What would be the ideal melee weapon made of "Phase Metal"?
What's the minimum number of sensors for a hobby GPS waypoint-following UAV?
Are neural networks prone to catastrophic forgetting?
Can I play a first turn Simic Growth Chamber to have 3 mana available in the second turn?
Professor falsely accusing me of cheating in a class he does not teach, two months after end of the class. What precautions should I take?
Does throwing a penny at a train stop the train?
During copyediting, journal disagrees about spelling of paper's main topic
Is Trump personally blocking people on Twitter?
Cops: The Hidden OEIS Substring
If the railway suggests a 5-min connection window for changing trains in the Netherlands, does that mean it's definitely doable?
Why isn't pressure filtration popular compared to vacuum filtration?
definition of "percentile"
What was the definition of "set" that resulted in Russell's Paradox
Why does my String turn into Integers instead of letters after I add characters with +?
How can I effectively communicate to recruiters that a phone call is not possible?
The monorail explodes before I can get on it
How might the United Kingdom become a republic?
<schwitz>, <zwinker> etc. Does German always use 2nd Person Singular Imperative verbs for emoticons? If so, why?
How can an advanced civilization forget how to manufacture its technology?
Minimizing expected brier score and Brier score interpretation
Initializing variables in an “if” statement
C++ IDE for Linux?What are the differences between a pointer variable and a reference variable in C++?Why can't variables be declared in a switch statement?Why use apparently meaningless do-while and if-else statements in macros?Declaring and initializing a variable in a Conditional or Control statement in C++What method do you use to initialize member variables?Best Practice when Declaring and Initializing variables in c++Do users need to fulfill any prerequisites to run C++17 software?C++11 brace/aggregate initialization. When to use it?Performance of recursive Variadic function calls against simple if..else statements
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I read that in C++17 we can initialize variables in if statements like this
if (int length = 2; length == 2)
//execute something
Instead of
int length = 2;
if (length == 2)
//do something
Even though it is shorter, it affects the code readability (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development.
Is there any advantage of using this feature other than making the code shorter?
c++ c++17
|
show 6 more comments
I read that in C++17 we can initialize variables in if statements like this
if (int length = 2; length == 2)
//execute something
Instead of
int length = 2;
if (length == 2)
//do something
Even though it is shorter, it affects the code readability (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development.
Is there any advantage of using this feature other than making the code shorter?
c++ c++17
32
Besides the scope thing?
– DeiDei
Jul 3 at 9:01
10
I guess someone have said few years back "I read that in C++11, we can create lambda statements like this (...) Even though it is shorter, it affects the code readibility (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development."
– R2RT
Jul 3 at 9:02
7
I'd say that it has exactly the same length, not shorter.
– VTT
Jul 3 at 9:12
5
pure opinion, hence not an answer:if (int length = 2; length == 2)is maybe surprising you see it the first time, but it is nothing complex that one could not understand so already the second time it wont be a big surprise anymore and declaring stuff in the scope where it belongs is one of the main factors contributing to readability. Imho your premise is wrong ;)
– formerlyknownas_463035818
Jul 3 at 9:15
12
Worrying about code readability for people who don't know the language in which the code is written (which is what "don't know this new feature" means) is a race to the bottom.
– another-dave
Jul 3 at 20:10
|
show 6 more comments
I read that in C++17 we can initialize variables in if statements like this
if (int length = 2; length == 2)
//execute something
Instead of
int length = 2;
if (length == 2)
//do something
Even though it is shorter, it affects the code readability (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development.
Is there any advantage of using this feature other than making the code shorter?
c++ c++17
I read that in C++17 we can initialize variables in if statements like this
if (int length = 2; length == 2)
//execute something
Instead of
int length = 2;
if (length == 2)
//do something
Even though it is shorter, it affects the code readability (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development.
Is there any advantage of using this feature other than making the code shorter?
c++ c++17
c++ c++17
edited yesterday
Fifoernik
8,2381 gold badge15 silver badges25 bronze badges
8,2381 gold badge15 silver badges25 bronze badges
asked Jul 3 at 8:58
ArneArne
6343 silver badges17 bronze badges
6343 silver badges17 bronze badges
32
Besides the scope thing?
– DeiDei
Jul 3 at 9:01
10
I guess someone have said few years back "I read that in C++11, we can create lambda statements like this (...) Even though it is shorter, it affects the code readibility (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development."
– R2RT
Jul 3 at 9:02
7
I'd say that it has exactly the same length, not shorter.
– VTT
Jul 3 at 9:12
5
pure opinion, hence not an answer:if (int length = 2; length == 2)is maybe surprising you see it the first time, but it is nothing complex that one could not understand so already the second time it wont be a big surprise anymore and declaring stuff in the scope where it belongs is one of the main factors contributing to readability. Imho your premise is wrong ;)
– formerlyknownas_463035818
Jul 3 at 9:15
12
Worrying about code readability for people who don't know the language in which the code is written (which is what "don't know this new feature" means) is a race to the bottom.
– another-dave
Jul 3 at 20:10
|
show 6 more comments
32
Besides the scope thing?
– DeiDei
Jul 3 at 9:01
10
I guess someone have said few years back "I read that in C++11, we can create lambda statements like this (...) Even though it is shorter, it affects the code readibility (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development."
– R2RT
Jul 3 at 9:02
7
I'd say that it has exactly the same length, not shorter.
– VTT
Jul 3 at 9:12
5
pure opinion, hence not an answer:if (int length = 2; length == 2)is maybe surprising you see it the first time, but it is nothing complex that one could not understand so already the second time it wont be a big surprise anymore and declaring stuff in the scope where it belongs is one of the main factors contributing to readability. Imho your premise is wrong ;)
– formerlyknownas_463035818
Jul 3 at 9:15
12
Worrying about code readability for people who don't know the language in which the code is written (which is what "don't know this new feature" means) is a race to the bottom.
– another-dave
Jul 3 at 20:10
32
32
Besides the scope thing?
– DeiDei
Jul 3 at 9:01
Besides the scope thing?
– DeiDei
Jul 3 at 9:01
10
10
I guess someone have said few years back "I read that in C++11, we can create lambda statements like this (...) Even though it is shorter, it affects the code readibility (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development."
– R2RT
Jul 3 at 9:02
I guess someone have said few years back "I read that in C++11, we can create lambda statements like this (...) Even though it is shorter, it affects the code readibility (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development."
– R2RT
Jul 3 at 9:02
7
7
I'd say that it has exactly the same length, not shorter.
– VTT
Jul 3 at 9:12
I'd say that it has exactly the same length, not shorter.
– VTT
Jul 3 at 9:12
5
5
pure opinion, hence not an answer:
if (int length = 2; length == 2) is maybe surprising you see it the first time, but it is nothing complex that one could not understand so already the second time it wont be a big surprise anymore and declaring stuff in the scope where it belongs is one of the main factors contributing to readability. Imho your premise is wrong ;)– formerlyknownas_463035818
Jul 3 at 9:15
pure opinion, hence not an answer:
if (int length = 2; length == 2) is maybe surprising you see it the first time, but it is nothing complex that one could not understand so already the second time it wont be a big surprise anymore and declaring stuff in the scope where it belongs is one of the main factors contributing to readability. Imho your premise is wrong ;)– formerlyknownas_463035818
Jul 3 at 9:15
12
12
Worrying about code readability for people who don't know the language in which the code is written (which is what "don't know this new feature" means) is a race to the bottom.
– another-dave
Jul 3 at 20:10
Worrying about code readability for people who don't know the language in which the code is written (which is what "don't know this new feature" means) is a race to the bottom.
– another-dave
Jul 3 at 20:10
|
show 6 more comments
6 Answers
6
active
oldest
votes
It limits the scope of length to the if alone. So you get the same benefits we originally got when we were allowed to write
for(int i = 0; i < ... ; ++i)
// ...
Instead of the variable leaking
int i;
for(i = 0; i < ... ; ++i)
// ...
Short lived variables are better for several reasons. But to name a couple:
The shorter something lives, the less things you need to keep in mind when reading unrelated lines of code. If
idoesn't exist outside the loop orifstatement, then we don't need to mind its value outside of them. Nor do we need to worry its value will interact with other parts of the program that are outside of its intended scope (which may happen ifiabove is reused in another loop). It makes code easier to follow and reason about.If the variable holds a resource, then that resource is now held for the shortest period possible. And this is without extraneous curly braces. It's also made clear the resource is related to the
ifalone. Consider this as a motivating exampleif(std::lock_guard _(mtx); guarded_thing.is_ready())
If your colleagues aren't aware of the feature, teach them! Appeasing programmers who don't wish to learn is a poor excuse to avoid features.
8
I'm going to grab this last sentence and slap it on a two-meter poster.
– Quentin
Jul 4 at 9:17
3
Also, short lived (tightly scoped) variables should reduce bugs because you can't accidentally reuse a variable later on in code once its purpose is served.
– Galik
Jul 4 at 10:37
1
Or with a weak pointer:if (auto p = ptr.lock(); p && p->foo()) bar(*p);
– Deduplicator
Jul 4 at 13:12
1
3. The compiler is allowed to reuse the stack space in more cases. (If you ever pass i by reference or pointer to an external function, for instance.)
– TLW
Jul 5 at 1:46
The better question might be "what is the advantage of this overint i = 2; if (i == 2) ..." (Note the additional scope.)
– TLW
Jul 5 at 1:47
add a comment |
Is there any advantage of using this feature other than making the code shorter?
You reduce variable scope. This does make sense and increases readability, as it strengthens the locality of identifiers you need to reason about. I agree that long init statements inside if statements should be avoided, but for short stuff, it's fine.
Note that you can already do initialization and branching on the result in pre-C++17:
int *get(); // returns nullptr under some condition
if (int *ptr = get())
doStuff();
This is subject to one's personal opinion, but you can consider an explicit condition more readable:
if (int *ptr = get(); ptr != nullptr)
doStuff();
Besides, arguing against the readability of a feature by referring to the fact that people aren't used to it is dangerous. People weren't used to smart pointers at some point, yet still we all agree today (I guess) that it's a good thing they are there.
4
you could useif (auto p =get ())since the operator bool is defined
– sudo rm -rf slash
Jul 4 at 6:18
add a comment |
The new form of the if statement has many uses.
Currently, the initializer is either declared before the statement and
leaked into the ambient scope, or an explicit scope is used. With the
new form, such code can be written more compactly, and the improved
scope control makes some erstwhile error-prone constructions a bit
more robust.
Open Standard Proposal for If statement with initializer

So, in summary, this statement simplifies common code patterns and helps users keep scopes tight.
I hope it helps!
Could you please make clear that you are quoting from the proposal? Especially the second paragraph. I suggest block-quotes.
– StoryTeller
Jul 3 at 9:09
Thanks @StoryTeller, Yes I quoted the second paragraph from the proposal of open-std which incorporated in C++17.
– Abhishek Sinha
Jul 3 at 9:12
add a comment |
In the interest of minimizing the scope of variables there is an idiom which defines a resource only if it is valid upon creation (for example file stream objects):
if(auto file = std::ifstream("filename"))
// use file here
else
// complain about errors here
// The identifier `file` does not pollute the wider scope
Sometimes you want to be able to reverse the logic of that test to make the failure the primary clause and the valid resource the else clause. This was previously not possible. But now we can do:
if(auto file = std::ifstream("filename"); !file)
// complain about errors here
else
// use file here
An example might be throwing an exception:
if(auto file = std::ifstream(filename); !file)
throw std::runtime_error(std::strerror(errno));
else
// use file here
Some people like to code so that a function will abort early on an error and otherwise progress. This idiom puts the abort logic physically above the continuation logic which some people may find more natural.
add a comment |
It is especially useful for logical events. Consider this example:
char op = '-';
if (op != '-' && op != '+' && op != '*' && op != '/')
std::cerr << "bad stuffn";
Seems a bit rough. Unless you are very familiar with OR, AND with negations, you might need to pause and think about this logic - which is generally poor design. With the if-initialization you can add expressiveness.
char op = '-';
if (bool op_valid = (op == '-') || (op == '+') || (op == '*') || (op == '/'); !op_valid)
std::cerr << "bad stuffn";
the named variable can be re-used inside the if too. E.g:
if (double distance = std::sqrt(a * a + b * b); distance < 0.5)
std::cerr << distance << " is too smalln";
This is great, especially given that the variable is scoped and therefore doesn't pollute the space afterwards.
3
So rough in fact that you made a logic error ;)
– Quentin
Jul 3 at 9:17
@Quentin that's embarassing. haha
– Stack Danny
Jul 3 at 9:18
2
I realize it's subjective, but I strongly prefer your "rough" version over the one with the if-initializer. I find it way easier to read and understand.
– Fabio Turati
Jul 4 at 10:15
@FabioTurati I suppose that is because you are very familiar with it and the other version is new. But over time I expect the if-initializer to outplay anything similar.
– Stack Danny
Jul 4 at 17:08
add a comment |
This is an extension of an existing feature, which aids readability in my experience.
if (auto* ptr = get_something())
Here we both create the variable ptr and we test against it being non-null. The scope of ptr is limited to where it is valid. It is far, far easier to convince yourself that all use of ptr is valid.
But what if we are talking about something that doesn't convert to bool that way?
if (auto itr = find(bob))
That doesn't work. But with this new feature we can:
if (auto itr = find(bob); itr != end())
Add a clause saying "when is this initialization valid".
In essence, this gives us a set of tokens that mean "initialize some expression, and when it is valid, do some code. When it is not valid, discard it."
It has been idiomatic to do the pointer-test trick since C++98. Once you have embraced that, this extension is natural.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56866458%2finitializing-variables-in-an-if-statement%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
It limits the scope of length to the if alone. So you get the same benefits we originally got when we were allowed to write
for(int i = 0; i < ... ; ++i)
// ...
Instead of the variable leaking
int i;
for(i = 0; i < ... ; ++i)
// ...
Short lived variables are better for several reasons. But to name a couple:
The shorter something lives, the less things you need to keep in mind when reading unrelated lines of code. If
idoesn't exist outside the loop orifstatement, then we don't need to mind its value outside of them. Nor do we need to worry its value will interact with other parts of the program that are outside of its intended scope (which may happen ifiabove is reused in another loop). It makes code easier to follow and reason about.If the variable holds a resource, then that resource is now held for the shortest period possible. And this is without extraneous curly braces. It's also made clear the resource is related to the
ifalone. Consider this as a motivating exampleif(std::lock_guard _(mtx); guarded_thing.is_ready())
If your colleagues aren't aware of the feature, teach them! Appeasing programmers who don't wish to learn is a poor excuse to avoid features.
8
I'm going to grab this last sentence and slap it on a two-meter poster.
– Quentin
Jul 4 at 9:17
3
Also, short lived (tightly scoped) variables should reduce bugs because you can't accidentally reuse a variable later on in code once its purpose is served.
– Galik
Jul 4 at 10:37
1
Or with a weak pointer:if (auto p = ptr.lock(); p && p->foo()) bar(*p);
– Deduplicator
Jul 4 at 13:12
1
3. The compiler is allowed to reuse the stack space in more cases. (If you ever pass i by reference or pointer to an external function, for instance.)
– TLW
Jul 5 at 1:46
The better question might be "what is the advantage of this overint i = 2; if (i == 2) ..." (Note the additional scope.)
– TLW
Jul 5 at 1:47
add a comment |
It limits the scope of length to the if alone. So you get the same benefits we originally got when we were allowed to write
for(int i = 0; i < ... ; ++i)
// ...
Instead of the variable leaking
int i;
for(i = 0; i < ... ; ++i)
// ...
Short lived variables are better for several reasons. But to name a couple:
The shorter something lives, the less things you need to keep in mind when reading unrelated lines of code. If
idoesn't exist outside the loop orifstatement, then we don't need to mind its value outside of them. Nor do we need to worry its value will interact with other parts of the program that are outside of its intended scope (which may happen ifiabove is reused in another loop). It makes code easier to follow and reason about.If the variable holds a resource, then that resource is now held for the shortest period possible. And this is without extraneous curly braces. It's also made clear the resource is related to the
ifalone. Consider this as a motivating exampleif(std::lock_guard _(mtx); guarded_thing.is_ready())
If your colleagues aren't aware of the feature, teach them! Appeasing programmers who don't wish to learn is a poor excuse to avoid features.
8
I'm going to grab this last sentence and slap it on a two-meter poster.
– Quentin
Jul 4 at 9:17
3
Also, short lived (tightly scoped) variables should reduce bugs because you can't accidentally reuse a variable later on in code once its purpose is served.
– Galik
Jul 4 at 10:37
1
Or with a weak pointer:if (auto p = ptr.lock(); p && p->foo()) bar(*p);
– Deduplicator
Jul 4 at 13:12
1
3. The compiler is allowed to reuse the stack space in more cases. (If you ever pass i by reference or pointer to an external function, for instance.)
– TLW
Jul 5 at 1:46
The better question might be "what is the advantage of this overint i = 2; if (i == 2) ..." (Note the additional scope.)
– TLW
Jul 5 at 1:47
add a comment |
It limits the scope of length to the if alone. So you get the same benefits we originally got when we were allowed to write
for(int i = 0; i < ... ; ++i)
// ...
Instead of the variable leaking
int i;
for(i = 0; i < ... ; ++i)
// ...
Short lived variables are better for several reasons. But to name a couple:
The shorter something lives, the less things you need to keep in mind when reading unrelated lines of code. If
idoesn't exist outside the loop orifstatement, then we don't need to mind its value outside of them. Nor do we need to worry its value will interact with other parts of the program that are outside of its intended scope (which may happen ifiabove is reused in another loop). It makes code easier to follow and reason about.If the variable holds a resource, then that resource is now held for the shortest period possible. And this is without extraneous curly braces. It's also made clear the resource is related to the
ifalone. Consider this as a motivating exampleif(std::lock_guard _(mtx); guarded_thing.is_ready())
If your colleagues aren't aware of the feature, teach them! Appeasing programmers who don't wish to learn is a poor excuse to avoid features.
It limits the scope of length to the if alone. So you get the same benefits we originally got when we were allowed to write
for(int i = 0; i < ... ; ++i)
// ...
Instead of the variable leaking
int i;
for(i = 0; i < ... ; ++i)
// ...
Short lived variables are better for several reasons. But to name a couple:
The shorter something lives, the less things you need to keep in mind when reading unrelated lines of code. If
idoesn't exist outside the loop orifstatement, then we don't need to mind its value outside of them. Nor do we need to worry its value will interact with other parts of the program that are outside of its intended scope (which may happen ifiabove is reused in another loop). It makes code easier to follow and reason about.If the variable holds a resource, then that resource is now held for the shortest period possible. And this is without extraneous curly braces. It's also made clear the resource is related to the
ifalone. Consider this as a motivating exampleif(std::lock_guard _(mtx); guarded_thing.is_ready())
If your colleagues aren't aware of the feature, teach them! Appeasing programmers who don't wish to learn is a poor excuse to avoid features.
edited yesterday
Fifoernik
8,2381 gold badge15 silver badges25 bronze badges
8,2381 gold badge15 silver badges25 bronze badges
answered Jul 3 at 9:02
StoryTellerStoryTeller
114k18 gold badges246 silver badges312 bronze badges
114k18 gold badges246 silver badges312 bronze badges
8
I'm going to grab this last sentence and slap it on a two-meter poster.
– Quentin
Jul 4 at 9:17
3
Also, short lived (tightly scoped) variables should reduce bugs because you can't accidentally reuse a variable later on in code once its purpose is served.
– Galik
Jul 4 at 10:37
1
Or with a weak pointer:if (auto p = ptr.lock(); p && p->foo()) bar(*p);
– Deduplicator
Jul 4 at 13:12
1
3. The compiler is allowed to reuse the stack space in more cases. (If you ever pass i by reference or pointer to an external function, for instance.)
– TLW
Jul 5 at 1:46
The better question might be "what is the advantage of this overint i = 2; if (i == 2) ..." (Note the additional scope.)
– TLW
Jul 5 at 1:47
add a comment |
8
I'm going to grab this last sentence and slap it on a two-meter poster.
– Quentin
Jul 4 at 9:17
3
Also, short lived (tightly scoped) variables should reduce bugs because you can't accidentally reuse a variable later on in code once its purpose is served.
– Galik
Jul 4 at 10:37
1
Or with a weak pointer:if (auto p = ptr.lock(); p && p->foo()) bar(*p);
– Deduplicator
Jul 4 at 13:12
1
3. The compiler is allowed to reuse the stack space in more cases. (If you ever pass i by reference or pointer to an external function, for instance.)
– TLW
Jul 5 at 1:46
The better question might be "what is the advantage of this overint i = 2; if (i == 2) ..." (Note the additional scope.)
– TLW
Jul 5 at 1:47
8
8
I'm going to grab this last sentence and slap it on a two-meter poster.
– Quentin
Jul 4 at 9:17
I'm going to grab this last sentence and slap it on a two-meter poster.
– Quentin
Jul 4 at 9:17
3
3
Also, short lived (tightly scoped) variables should reduce bugs because you can't accidentally reuse a variable later on in code once its purpose is served.
– Galik
Jul 4 at 10:37
Also, short lived (tightly scoped) variables should reduce bugs because you can't accidentally reuse a variable later on in code once its purpose is served.
– Galik
Jul 4 at 10:37
1
1
Or with a weak pointer:
if (auto p = ptr.lock(); p && p->foo()) bar(*p);– Deduplicator
Jul 4 at 13:12
Or with a weak pointer:
if (auto p = ptr.lock(); p && p->foo()) bar(*p);– Deduplicator
Jul 4 at 13:12
1
1
3. The compiler is allowed to reuse the stack space in more cases. (If you ever pass i by reference or pointer to an external function, for instance.)
– TLW
Jul 5 at 1:46
3. The compiler is allowed to reuse the stack space in more cases. (If you ever pass i by reference or pointer to an external function, for instance.)
– TLW
Jul 5 at 1:46
The better question might be "what is the advantage of this over
int i = 2; if (i == 2) ..." (Note the additional scope.)– TLW
Jul 5 at 1:47
The better question might be "what is the advantage of this over
int i = 2; if (i == 2) ..." (Note the additional scope.)– TLW
Jul 5 at 1:47
add a comment |
Is there any advantage of using this feature other than making the code shorter?
You reduce variable scope. This does make sense and increases readability, as it strengthens the locality of identifiers you need to reason about. I agree that long init statements inside if statements should be avoided, but for short stuff, it's fine.
Note that you can already do initialization and branching on the result in pre-C++17:
int *get(); // returns nullptr under some condition
if (int *ptr = get())
doStuff();
This is subject to one's personal opinion, but you can consider an explicit condition more readable:
if (int *ptr = get(); ptr != nullptr)
doStuff();
Besides, arguing against the readability of a feature by referring to the fact that people aren't used to it is dangerous. People weren't used to smart pointers at some point, yet still we all agree today (I guess) that it's a good thing they are there.
4
you could useif (auto p =get ())since the operator bool is defined
– sudo rm -rf slash
Jul 4 at 6:18
add a comment |
Is there any advantage of using this feature other than making the code shorter?
You reduce variable scope. This does make sense and increases readability, as it strengthens the locality of identifiers you need to reason about. I agree that long init statements inside if statements should be avoided, but for short stuff, it's fine.
Note that you can already do initialization and branching on the result in pre-C++17:
int *get(); // returns nullptr under some condition
if (int *ptr = get())
doStuff();
This is subject to one's personal opinion, but you can consider an explicit condition more readable:
if (int *ptr = get(); ptr != nullptr)
doStuff();
Besides, arguing against the readability of a feature by referring to the fact that people aren't used to it is dangerous. People weren't used to smart pointers at some point, yet still we all agree today (I guess) that it's a good thing they are there.
4
you could useif (auto p =get ())since the operator bool is defined
– sudo rm -rf slash
Jul 4 at 6:18
add a comment |
Is there any advantage of using this feature other than making the code shorter?
You reduce variable scope. This does make sense and increases readability, as it strengthens the locality of identifiers you need to reason about. I agree that long init statements inside if statements should be avoided, but for short stuff, it's fine.
Note that you can already do initialization and branching on the result in pre-C++17:
int *get(); // returns nullptr under some condition
if (int *ptr = get())
doStuff();
This is subject to one's personal opinion, but you can consider an explicit condition more readable:
if (int *ptr = get(); ptr != nullptr)
doStuff();
Besides, arguing against the readability of a feature by referring to the fact that people aren't used to it is dangerous. People weren't used to smart pointers at some point, yet still we all agree today (I guess) that it's a good thing they are there.
Is there any advantage of using this feature other than making the code shorter?
You reduce variable scope. This does make sense and increases readability, as it strengthens the locality of identifiers you need to reason about. I agree that long init statements inside if statements should be avoided, but for short stuff, it's fine.
Note that you can already do initialization and branching on the result in pre-C++17:
int *get(); // returns nullptr under some condition
if (int *ptr = get())
doStuff();
This is subject to one's personal opinion, but you can consider an explicit condition more readable:
if (int *ptr = get(); ptr != nullptr)
doStuff();
Besides, arguing against the readability of a feature by referring to the fact that people aren't used to it is dangerous. People weren't used to smart pointers at some point, yet still we all agree today (I guess) that it's a good thing they are there.
edited Jul 3 at 9:27
answered Jul 3 at 9:02
lubgrlubgr
22k3 gold badges31 silver badges74 bronze badges
22k3 gold badges31 silver badges74 bronze badges
4
you could useif (auto p =get ())since the operator bool is defined
– sudo rm -rf slash
Jul 4 at 6:18
add a comment |
4
you could useif (auto p =get ())since the operator bool is defined
– sudo rm -rf slash
Jul 4 at 6:18
4
4
you could use
if (auto p =get ()) since the operator bool is defined– sudo rm -rf slash
Jul 4 at 6:18
you could use
if (auto p =get ()) since the operator bool is defined– sudo rm -rf slash
Jul 4 at 6:18
add a comment |
The new form of the if statement has many uses.
Currently, the initializer is either declared before the statement and
leaked into the ambient scope, or an explicit scope is used. With the
new form, such code can be written more compactly, and the improved
scope control makes some erstwhile error-prone constructions a bit
more robust.
Open Standard Proposal for If statement with initializer

So, in summary, this statement simplifies common code patterns and helps users keep scopes tight.
I hope it helps!
Could you please make clear that you are quoting from the proposal? Especially the second paragraph. I suggest block-quotes.
– StoryTeller
Jul 3 at 9:09
Thanks @StoryTeller, Yes I quoted the second paragraph from the proposal of open-std which incorporated in C++17.
– Abhishek Sinha
Jul 3 at 9:12
add a comment |
The new form of the if statement has many uses.
Currently, the initializer is either declared before the statement and
leaked into the ambient scope, or an explicit scope is used. With the
new form, such code can be written more compactly, and the improved
scope control makes some erstwhile error-prone constructions a bit
more robust.
Open Standard Proposal for If statement with initializer

So, in summary, this statement simplifies common code patterns and helps users keep scopes tight.
I hope it helps!
Could you please make clear that you are quoting from the proposal? Especially the second paragraph. I suggest block-quotes.
– StoryTeller
Jul 3 at 9:09
Thanks @StoryTeller, Yes I quoted the second paragraph from the proposal of open-std which incorporated in C++17.
– Abhishek Sinha
Jul 3 at 9:12
add a comment |
The new form of the if statement has many uses.
Currently, the initializer is either declared before the statement and
leaked into the ambient scope, or an explicit scope is used. With the
new form, such code can be written more compactly, and the improved
scope control makes some erstwhile error-prone constructions a bit
more robust.
Open Standard Proposal for If statement with initializer

So, in summary, this statement simplifies common code patterns and helps users keep scopes tight.
I hope it helps!
The new form of the if statement has many uses.
Currently, the initializer is either declared before the statement and
leaked into the ambient scope, or an explicit scope is used. With the
new form, such code can be written more compactly, and the improved
scope control makes some erstwhile error-prone constructions a bit
more robust.
Open Standard Proposal for If statement with initializer

So, in summary, this statement simplifies common code patterns and helps users keep scopes tight.
I hope it helps!
edited Jul 3 at 9:12
StoryTeller
114k18 gold badges246 silver badges312 bronze badges
114k18 gold badges246 silver badges312 bronze badges
answered Jul 3 at 9:06
Abhishek SinhaAbhishek Sinha
4111 silver badge6 bronze badges
4111 silver badge6 bronze badges
Could you please make clear that you are quoting from the proposal? Especially the second paragraph. I suggest block-quotes.
– StoryTeller
Jul 3 at 9:09
Thanks @StoryTeller, Yes I quoted the second paragraph from the proposal of open-std which incorporated in C++17.
– Abhishek Sinha
Jul 3 at 9:12
add a comment |
Could you please make clear that you are quoting from the proposal? Especially the second paragraph. I suggest block-quotes.
– StoryTeller
Jul 3 at 9:09
Thanks @StoryTeller, Yes I quoted the second paragraph from the proposal of open-std which incorporated in C++17.
– Abhishek Sinha
Jul 3 at 9:12
Could you please make clear that you are quoting from the proposal? Especially the second paragraph. I suggest block-quotes.
– StoryTeller
Jul 3 at 9:09
Could you please make clear that you are quoting from the proposal? Especially the second paragraph. I suggest block-quotes.
– StoryTeller
Jul 3 at 9:09
Thanks @StoryTeller, Yes I quoted the second paragraph from the proposal of open-std which incorporated in C++17.
– Abhishek Sinha
Jul 3 at 9:12
Thanks @StoryTeller, Yes I quoted the second paragraph from the proposal of open-std which incorporated in C++17.
– Abhishek Sinha
Jul 3 at 9:12
add a comment |
In the interest of minimizing the scope of variables there is an idiom which defines a resource only if it is valid upon creation (for example file stream objects):
if(auto file = std::ifstream("filename"))
// use file here
else
// complain about errors here
// The identifier `file` does not pollute the wider scope
Sometimes you want to be able to reverse the logic of that test to make the failure the primary clause and the valid resource the else clause. This was previously not possible. But now we can do:
if(auto file = std::ifstream("filename"); !file)
// complain about errors here
else
// use file here
An example might be throwing an exception:
if(auto file = std::ifstream(filename); !file)
throw std::runtime_error(std::strerror(errno));
else
// use file here
Some people like to code so that a function will abort early on an error and otherwise progress. This idiom puts the abort logic physically above the continuation logic which some people may find more natural.
add a comment |
In the interest of minimizing the scope of variables there is an idiom which defines a resource only if it is valid upon creation (for example file stream objects):
if(auto file = std::ifstream("filename"))
// use file here
else
// complain about errors here
// The identifier `file` does not pollute the wider scope
Sometimes you want to be able to reverse the logic of that test to make the failure the primary clause and the valid resource the else clause. This was previously not possible. But now we can do:
if(auto file = std::ifstream("filename"); !file)
// complain about errors here
else
// use file here
An example might be throwing an exception:
if(auto file = std::ifstream(filename); !file)
throw std::runtime_error(std::strerror(errno));
else
// use file here
Some people like to code so that a function will abort early on an error and otherwise progress. This idiom puts the abort logic physically above the continuation logic which some people may find more natural.
add a comment |
In the interest of minimizing the scope of variables there is an idiom which defines a resource only if it is valid upon creation (for example file stream objects):
if(auto file = std::ifstream("filename"))
// use file here
else
// complain about errors here
// The identifier `file` does not pollute the wider scope
Sometimes you want to be able to reverse the logic of that test to make the failure the primary clause and the valid resource the else clause. This was previously not possible. But now we can do:
if(auto file = std::ifstream("filename"); !file)
// complain about errors here
else
// use file here
An example might be throwing an exception:
if(auto file = std::ifstream(filename); !file)
throw std::runtime_error(std::strerror(errno));
else
// use file here
Some people like to code so that a function will abort early on an error and otherwise progress. This idiom puts the abort logic physically above the continuation logic which some people may find more natural.
In the interest of minimizing the scope of variables there is an idiom which defines a resource only if it is valid upon creation (for example file stream objects):
if(auto file = std::ifstream("filename"))
// use file here
else
// complain about errors here
// The identifier `file` does not pollute the wider scope
Sometimes you want to be able to reverse the logic of that test to make the failure the primary clause and the valid resource the else clause. This was previously not possible. But now we can do:
if(auto file = std::ifstream("filename"); !file)
// complain about errors here
else
// use file here
An example might be throwing an exception:
if(auto file = std::ifstream(filename); !file)
throw std::runtime_error(std::strerror(errno));
else
// use file here
Some people like to code so that a function will abort early on an error and otherwise progress. This idiom puts the abort logic physically above the continuation logic which some people may find more natural.
edited Jul 4 at 10:26
answered Jul 3 at 9:15
GalikGalik
36.4k3 gold badges60 silver badges85 bronze badges
36.4k3 gold badges60 silver badges85 bronze badges
add a comment |
add a comment |
It is especially useful for logical events. Consider this example:
char op = '-';
if (op != '-' && op != '+' && op != '*' && op != '/')
std::cerr << "bad stuffn";
Seems a bit rough. Unless you are very familiar with OR, AND with negations, you might need to pause and think about this logic - which is generally poor design. With the if-initialization you can add expressiveness.
char op = '-';
if (bool op_valid = (op == '-') || (op == '+') || (op == '*') || (op == '/'); !op_valid)
std::cerr << "bad stuffn";
the named variable can be re-used inside the if too. E.g:
if (double distance = std::sqrt(a * a + b * b); distance < 0.5)
std::cerr << distance << " is too smalln";
This is great, especially given that the variable is scoped and therefore doesn't pollute the space afterwards.
3
So rough in fact that you made a logic error ;)
– Quentin
Jul 3 at 9:17
@Quentin that's embarassing. haha
– Stack Danny
Jul 3 at 9:18
2
I realize it's subjective, but I strongly prefer your "rough" version over the one with the if-initializer. I find it way easier to read and understand.
– Fabio Turati
Jul 4 at 10:15
@FabioTurati I suppose that is because you are very familiar with it and the other version is new. But over time I expect the if-initializer to outplay anything similar.
– Stack Danny
Jul 4 at 17:08
add a comment |
It is especially useful for logical events. Consider this example:
char op = '-';
if (op != '-' && op != '+' && op != '*' && op != '/')
std::cerr << "bad stuffn";
Seems a bit rough. Unless you are very familiar with OR, AND with negations, you might need to pause and think about this logic - which is generally poor design. With the if-initialization you can add expressiveness.
char op = '-';
if (bool op_valid = (op == '-') || (op == '+') || (op == '*') || (op == '/'); !op_valid)
std::cerr << "bad stuffn";
the named variable can be re-used inside the if too. E.g:
if (double distance = std::sqrt(a * a + b * b); distance < 0.5)
std::cerr << distance << " is too smalln";
This is great, especially given that the variable is scoped and therefore doesn't pollute the space afterwards.
3
So rough in fact that you made a logic error ;)
– Quentin
Jul 3 at 9:17
@Quentin that's embarassing. haha
– Stack Danny
Jul 3 at 9:18
2
I realize it's subjective, but I strongly prefer your "rough" version over the one with the if-initializer. I find it way easier to read and understand.
– Fabio Turati
Jul 4 at 10:15
@FabioTurati I suppose that is because you are very familiar with it and the other version is new. But over time I expect the if-initializer to outplay anything similar.
– Stack Danny
Jul 4 at 17:08
add a comment |
It is especially useful for logical events. Consider this example:
char op = '-';
if (op != '-' && op != '+' && op != '*' && op != '/')
std::cerr << "bad stuffn";
Seems a bit rough. Unless you are very familiar with OR, AND with negations, you might need to pause and think about this logic - which is generally poor design. With the if-initialization you can add expressiveness.
char op = '-';
if (bool op_valid = (op == '-') || (op == '+') || (op == '*') || (op == '/'); !op_valid)
std::cerr << "bad stuffn";
the named variable can be re-used inside the if too. E.g:
if (double distance = std::sqrt(a * a + b * b); distance < 0.5)
std::cerr << distance << " is too smalln";
This is great, especially given that the variable is scoped and therefore doesn't pollute the space afterwards.
It is especially useful for logical events. Consider this example:
char op = '-';
if (op != '-' && op != '+' && op != '*' && op != '/')
std::cerr << "bad stuffn";
Seems a bit rough. Unless you are very familiar with OR, AND with negations, you might need to pause and think about this logic - which is generally poor design. With the if-initialization you can add expressiveness.
char op = '-';
if (bool op_valid = (op == '-') || (op == '+') || (op == '*') || (op == '/'); !op_valid)
std::cerr << "bad stuffn";
the named variable can be re-used inside the if too. E.g:
if (double distance = std::sqrt(a * a + b * b); distance < 0.5)
std::cerr << distance << " is too smalln";
This is great, especially given that the variable is scoped and therefore doesn't pollute the space afterwards.
edited Jul 3 at 9:31
answered Jul 3 at 9:16
Stack DannyStack Danny
3,35610 silver badges39 bronze badges
3,35610 silver badges39 bronze badges
3
So rough in fact that you made a logic error ;)
– Quentin
Jul 3 at 9:17
@Quentin that's embarassing. haha
– Stack Danny
Jul 3 at 9:18
2
I realize it's subjective, but I strongly prefer your "rough" version over the one with the if-initializer. I find it way easier to read and understand.
– Fabio Turati
Jul 4 at 10:15
@FabioTurati I suppose that is because you are very familiar with it and the other version is new. But over time I expect the if-initializer to outplay anything similar.
– Stack Danny
Jul 4 at 17:08
add a comment |
3
So rough in fact that you made a logic error ;)
– Quentin
Jul 3 at 9:17
@Quentin that's embarassing. haha
– Stack Danny
Jul 3 at 9:18
2
I realize it's subjective, but I strongly prefer your "rough" version over the one with the if-initializer. I find it way easier to read and understand.
– Fabio Turati
Jul 4 at 10:15
@FabioTurati I suppose that is because you are very familiar with it and the other version is new. But over time I expect the if-initializer to outplay anything similar.
– Stack Danny
Jul 4 at 17:08
3
3
So rough in fact that you made a logic error ;)
– Quentin
Jul 3 at 9:17
So rough in fact that you made a logic error ;)
– Quentin
Jul 3 at 9:17
@Quentin that's embarassing. haha
– Stack Danny
Jul 3 at 9:18
@Quentin that's embarassing. haha
– Stack Danny
Jul 3 at 9:18
2
2
I realize it's subjective, but I strongly prefer your "rough" version over the one with the if-initializer. I find it way easier to read and understand.
– Fabio Turati
Jul 4 at 10:15
I realize it's subjective, but I strongly prefer your "rough" version over the one with the if-initializer. I find it way easier to read and understand.
– Fabio Turati
Jul 4 at 10:15
@FabioTurati I suppose that is because you are very familiar with it and the other version is new. But over time I expect the if-initializer to outplay anything similar.
– Stack Danny
Jul 4 at 17:08
@FabioTurati I suppose that is because you are very familiar with it and the other version is new. But over time I expect the if-initializer to outplay anything similar.
– Stack Danny
Jul 4 at 17:08
add a comment |
This is an extension of an existing feature, which aids readability in my experience.
if (auto* ptr = get_something())
Here we both create the variable ptr and we test against it being non-null. The scope of ptr is limited to where it is valid. It is far, far easier to convince yourself that all use of ptr is valid.
But what if we are talking about something that doesn't convert to bool that way?
if (auto itr = find(bob))
That doesn't work. But with this new feature we can:
if (auto itr = find(bob); itr != end())
Add a clause saying "when is this initialization valid".
In essence, this gives us a set of tokens that mean "initialize some expression, and when it is valid, do some code. When it is not valid, discard it."
It has been idiomatic to do the pointer-test trick since C++98. Once you have embraced that, this extension is natural.
add a comment |
This is an extension of an existing feature, which aids readability in my experience.
if (auto* ptr = get_something())
Here we both create the variable ptr and we test against it being non-null. The scope of ptr is limited to where it is valid. It is far, far easier to convince yourself that all use of ptr is valid.
But what if we are talking about something that doesn't convert to bool that way?
if (auto itr = find(bob))
That doesn't work. But with this new feature we can:
if (auto itr = find(bob); itr != end())
Add a clause saying "when is this initialization valid".
In essence, this gives us a set of tokens that mean "initialize some expression, and when it is valid, do some code. When it is not valid, discard it."
It has been idiomatic to do the pointer-test trick since C++98. Once you have embraced that, this extension is natural.
add a comment |
This is an extension of an existing feature, which aids readability in my experience.
if (auto* ptr = get_something())
Here we both create the variable ptr and we test against it being non-null. The scope of ptr is limited to where it is valid. It is far, far easier to convince yourself that all use of ptr is valid.
But what if we are talking about something that doesn't convert to bool that way?
if (auto itr = find(bob))
That doesn't work. But with this new feature we can:
if (auto itr = find(bob); itr != end())
Add a clause saying "when is this initialization valid".
In essence, this gives us a set of tokens that mean "initialize some expression, and when it is valid, do some code. When it is not valid, discard it."
It has been idiomatic to do the pointer-test trick since C++98. Once you have embraced that, this extension is natural.
This is an extension of an existing feature, which aids readability in my experience.
if (auto* ptr = get_something())
Here we both create the variable ptr and we test against it being non-null. The scope of ptr is limited to where it is valid. It is far, far easier to convince yourself that all use of ptr is valid.
But what if we are talking about something that doesn't convert to bool that way?
if (auto itr = find(bob))
That doesn't work. But with this new feature we can:
if (auto itr = find(bob); itr != end())
Add a clause saying "when is this initialization valid".
In essence, this gives us a set of tokens that mean "initialize some expression, and when it is valid, do some code. When it is not valid, discard it."
It has been idiomatic to do the pointer-test trick since C++98. Once you have embraced that, this extension is natural.
edited Jul 6 at 12:22
Peter Mortensen
14.2k19 gold badges88 silver badges115 bronze badges
14.2k19 gold badges88 silver badges115 bronze badges
answered Jul 4 at 15:29
Yakk - Adam NevraumontYakk - Adam Nevraumont
195k21 gold badges214 silver badges403 bronze badges
195k21 gold badges214 silver badges403 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56866458%2finitializing-variables-in-an-if-statement%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
32
Besides the scope thing?
– DeiDei
Jul 3 at 9:01
10
I guess someone have said few years back "I read that in C++11, we can create lambda statements like this (...) Even though it is shorter, it affects the code readibility (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development."
– R2RT
Jul 3 at 9:02
7
I'd say that it has exactly the same length, not shorter.
– VTT
Jul 3 at 9:12
5
pure opinion, hence not an answer:
if (int length = 2; length == 2)is maybe surprising you see it the first time, but it is nothing complex that one could not understand so already the second time it wont be a big surprise anymore and declaring stuff in the scope where it belongs is one of the main factors contributing to readability. Imho your premise is wrong ;)– formerlyknownas_463035818
Jul 3 at 9:15
12
Worrying about code readability for people who don't know the language in which the code is written (which is what "don't know this new feature" means) is a race to the bottom.
– another-dave
Jul 3 at 20:10