How to declare a variable in brackets of if statement?

I want to declare a local variable in the brackets of the if statement. For example.

if((char c = getc(stdin)) == 0x01)//This is not OK with g++. { ungetc(c, stdin); } 

I want to see if the one I want. To say this normally, I want to use a variable (char c) both in the if line and in the if body, but not outside the if.

But g ++ (GCC 4.8.1) says the expected primary expression before

 char c = getc(stdin); if(c == 0x01) { bla... } 
+7
c ++ c ++ 11
source share
3 answers

If this is a pollution of the namespace you are worried about, you can always define an if in a block:

 { char c = getc(stdin); if(c == 0x01) { // ... } } 

So c will only work until the end of the block is reached.

+17
source share

I did not know how to create a variable and check its value with if until we saw some of the published solutions. However, you can use switch . This will allow you to respond to additional values ​​(possibly EOF ):

 switch (int c = getc(stdin)) { case 0x01: ungetc(c, stdin); break; case EOF: // ...handle EOF default: break; } 

You can always put an if in an inline function, and the code will look a little cleaner. If you really want the source code to be correct in this place, but without creating a new area around the if with a new variable, perhaps a lambda would be acceptable to you.

 [](int c){ if (c == 0x01) ungetc(c, stdin); }(getc(stdin)); 

Since you are comparing only one value, your specific problem does not require a variable at all, so you can simply do:

 if (getc(stdin) == 0x01) { char c = 0x01; ungetc(c, stdin); //or bla... } 

If you want to compare with a set of values, a switch clause is a better option.

Jerry Coffin's solution looks attractive, but it really comes down to:

 if (int c = (getc(stdin) == 0x01)) //... 

This is probably not what you really wanted, as it does not generalize very well if you want to compare with a value other than 0x01 .

Potatoswatter's solution seems closer to what you want, but it might be better to bring the type to a standalone class:

 template <typename T> class SetAndTest { const T test_; T set_; public: SetAndTest (T s = T(), T t = T()) : set_(s), test_(t) {} operator bool () { return set_ == test_; } operator bool () const { return set_ == test_; } operator T & () { return set_; } operator T () const { return set_; } }; //... if (auto c = SetAndTest<int>(getc(stdin), 0x01)) { ungetc(c, stdin); //or bla... } 
+10
source share

You can easily define a variable inside an if . For example, this should compile:

 if (int ch = getchar()) ; 

The problem is that the type (e.g. int ) should follow immediately after opening the bracket. The extra bracket that you have is causing the compilation to fail. So, if you really want to do this, you need to think a little and use something like this:

 if (char ch = 0 || ((ch = getchar()) == 0x1)) 

This allows you to get the creation and initialization of ch done, after this part of the expression is completed, put in parentheses around ch=getchar() to redefine the priority of destination and comparison.

Please note that && and || perform a short circuit assessment, so you need to be careful with your initialization. You can use either:

 if (char ch = 0 || ... 

... or:

 if (char ch = 1 && ... 

... but if you try to use if (ch = 1 || ... or if (ch = 0 && ... , the short circuit assessment will contain the correct operand (the part you really care about).

Now a word of caution: although I am sure that this code meets the standard requirements, and most (all?) Compilers will accept it, this will probably cause most programmers reading the code a serious scratch on their heads, figuring out what you have done and why. I would very much not dare (at best) to use this "technique" in real code.

Edit: It was pointed out that the result of this may be even more misleading than originally expected, so I will try to clarify the situation. It happens that the value is read from the input. This value is assigned to ch and is compared with 0x1 . So far, so good. After that, the comparison result (converted to an integer, therefore either 0 or 1 ) will be assigned to ch . I believe that it has a sufficient sequence of points, that the result is determined by behavior. But this is probably not what you, or anyone, want - thus, advice that you probably don't want to use, and a mention that it would probably leave most programmers scratching their heads, wondering the question is what were you trying to do. In the most specific case of comparison with 0x1, the value of ch inside the if will be 1 , but this is more or less a coincidence. If you were comparing with 0x2, the value of ch inside the if would still be 1 , not 2 .

+8
source share

All Articles