23

Possible Duplicate:
Declaring and initializing a variable in a Conditional or Control statement in C++

Instead of this...

int value = get_value();
if ( value > 100 )
{
    // Do something with value.
}

... is it possible to reduce the scope of value to only where it is needed:

if ( int value = get_value() > 100 )
{
    // Obviously this doesn't work. get_value() > 100 returns true,
    // which is implicitly converted to 1 and assigned to value.
}
Community
  • 1
  • 1
x-x
  • 7,287
  • 9
  • 51
  • 78

7 Answers7

22

If you want specific scope for value, you can introduce a scope block.

#include <iostream>

int get_value() {
    return 101;
}

int main() {
    {
        int value = get_value();
        if(value > 100)
            std::cout << "Hey!";
    } //value out of scope
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Rapptz
  • 20,807
  • 5
  • 72
  • 86
13

Can you declare a variable and compare it within the if() statement? No.
Can you declare a variable and compare it in such a way that the scope is tightly-bound to the if() block? Yes!


You can either declare a variable:

if (int x = 5) {
   // lol!
}

or you can do things with one:

int x = foo();
if (x == 5) {
   // wahey!
}

You can't do both!


You can cheat a little where the only thing you need to do is compare with true, because the declaration itself evaluates to the value of the new object.

So, if you have:

int foo()
{
   return 0;
}

Then this:

if (int x = foo()) {
    // never reached
}

is equivalent to:

{
   int x = foo();
   if (x) {
       // never reached
   }
}

This final syntax, using a standalone scope block, is also your golden bullet for more complex expressions:

{
   int x = foo();
   if (x > bar()) {
       // wahooza!
   }
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • @Hi-Angel: Did you post your comment on the wrong answer? It appears to have nothing to do with what I said. There is nothing "brittle" about basic `if` syntax, which will always "work". – Lightness Races in Orbit May 17 '18 at 09:34
6

Put it in a function:

void goodName(int value) {
    if(value > 100) {
        // Do something with value.
    }
}

//...
    goodName(get_value());
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
5

How about using for instead?

for (int value = get_value(); value > 100; value = 0) {
    //...
}

If you want to go C++11 on it, you can use a lambda:

[](int value = get_value()) {
    if (value > 100) {
        //...
        std::cout << "value:" << value;
    }
}();
jxh
  • 69,070
  • 8
  • 110
  • 193
1

Or you could just add an extra set of braces for a nested scope, although it's not exactly pretty:

{
    int value = get_value();
    if ( value > 100 )
    {
        // Do something with value.
    }   
}
//now value is out of scope
yumaikas
  • 979
  • 13
  • 24
1

You can write a small function which can do the comparison for you and return the value the if comparison returns true, else return 0 to avoid executing the if block:

int greater_than(int right, int left)
{
   return left > right ? left : 0;
}

Then use it as:

if ( int value = greater_than(100, get_value()))
{
      //wow!
}

Or you can use for as other answer said. Or manually put braces to reduce the scope of the variable.

At any rate, I would not write such code in production code.

Don't write code for machines. Write code for humans. Machines will understand anything as long as you follow their grammar; humans understand what is readable to them. So readability should be your priority over unnecessary scoping.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
0

In this particular case, you can bodge it:

if (int value = (get_value() > 100 ? get_value() : 0)) {
    ...
}

I don't really recommend it, though. It doesn't work for all possible tests that you might want to perform, and it calls get_value() twice.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • Why not `if(get_value() > 100) { int value = get_value(); ....}` – Nawaz Jan 31 '13 at 08:32
  • @Nawaz: because the questioner posed a contrived restriction (i.e. no good reason -- I wouldn't write this in real code and your suggestion is better). In fact, if the number of calls to `get_value()` doesn't matter then I probably wouldn't assign it to a variable at all, just type `get_value()` in the body of the loop however many times it's needed :-) – Steve Jessop Jan 31 '13 at 08:33
  • 2
    @SteveJessop: No good reason? Restricting the scope of variables isn't "no good reason" :) – x-x Feb 01 '13 at 04:25
  • @DrTwox: sure, but adding the extra block is the "real" answer I'd have given if it wasn't already mentioned, or if calling `get_value()` twice is OK then what Nawaz says in the comment above beats this when there is no `else` clause. Actually Nawaz's answer is a potential improvement on this anyway. I'd tinker a bit with it, I don't *love* the idea of a function whose first param is called `right` and the second `left`! – Steve Jessop Feb 02 '13 at 08:46