Using assignment as a condition expression?
Asked Answered
D

5

14

Consider:

if (a=5) {
   /* do something */
}

How does the assignment work as a condition?

Is it based on non-zero value of l-value?

Dogma answered 24/7, 2011 at 14:28 Comment(8)
Are you compiling in C++ or C?Shawndashawnee
int war = false; if(war = true) { launchnuke(); }Pricillaprick
@WTP: Never compare a boolean to anything. A boolean is already boolean: if (war) launchnuke(); And programmers who assigns true or false to a non-boolean deserves all kinds of meyham launched against them.Professorate
@David: Where did WTP compare a boolean to a boolean?Haplology
@Tomalak: He didn't, but if(var = true) was probably intended to be if(var == true). Writing it as if (var) in the first place would have neatly avoided the potential = vs. ==' confusion.Utley
@Keith: Given the subject matter, I'm fairly certain that he was being ironic.Haplology
@George: Accept answers to your questions, please.Haplology
@WTP That made my day :-)Romanism
H
30

C++ — ISO/IEC 14882:2003(E)

[5.17/1] There are several assignment operators, all of which group right-to-left. All require a modifiable lvalue as their left operand, and the type of an assignment expression is that of its left operand. The result of the assignment operation is the value stored in the left operand after the assignment has taken place; the result is an lvalue.

The result of the expression a = 5 is 5.

[6.4/4] [..] The value of a condition that is an expression is the value of the expression, implicitly converted to bool for statements other than switch. [..]

A conversion to bool takes place.

[4.12/1] An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.

5 converts to boolean true.

[6.4.1/1] If the condition (6.4) yields true the first substatement is executed. [..]

true is treated as an if statement success.


C — ISO/IEC 9899:1999(E)

[6.5.16/3] An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue. [..]

The result of the expression a = 5 is 5.

[6.8.4.1/2] In both forms, the first substatement is executed if the expression compares unequal to 0. [..]

5 is treated as an if statement success.


General

Code like this is almost always a mistake; the author likely intended if (a == 5) {}. However, sometimes it is deliberate. You may see code like this:

if (x = foo()) {
   cout << "I set x to the result of foo(), which is truthy";
   // ... stuff
}
Haplology answered 24/7, 2011 at 14:30 Comment(6)
To make sure it's no mistake you can write if ((a=5) != 0) which is semantically the same as if (a=5).Claudie
Will 0.0 be considered as zero value?Hydraulic
@Stan: Looks like zero to me! (Though recall that floating-point is inaccurate.)Haplology
Since the question is tagged both C and C++ it might be nice to mention you're citing C++, not C. The reasoning is rather different for the two.Lemuel
@Tomalak Geret'kal: Fonts could be a little smaller.Nyctaginaceous
@Tomalak Geret'kal: Naah, The answer is very good, but those BIG heading fonts really hurt the eyes :)Nyctaginaceous
S
1

if(a=x) is equivalent to if(x) in addition to a assigned with x. So if the expression x evaluates to a non-zero value, then if(x) simply becomes if(true). Otherwise, it becomes if(false).

In your case, since x = 5, that means f(a=5) is equivalent to if(true) in addition to a assigned with 5.

Skiagraph answered 24/7, 2011 at 14:33 Comment(3)
This is a bit misleading: if(a=5) is not equivalent to if(true) because it also assigns a.Beall
-1: if (a = x)' and if (x)' are not equivalent, the first expression has a side-effect.Lenlena
@interjay: I just edited this, when you both were commenting.Skiagraph
H
1

Every non-zero value will be considered as true.

So some people will suggest you write

5 == a

to avoid that you make mistake == by =.

Hydraulic answered 24/7, 2011 at 14:33 Comment(6)
Most compilers will warn about that mistake nowadays.Kana
@Bo Persson: surely it is. But some lazy people would like to turn off the warning, so let's make it an error than a warning.Hydraulic
-1: To me this is ugly and does not provide a general solution.Lenlena
I don't suggest writing 5 == a. I suggest writing a == 5. :) Just do it; it's not hard. And if you're turning off warnings then you deserve everything you get.Haplology
@Tomalak Geret'kal: well I agree with you. So I said 'some people' but not just 'I'. Of course '5==a' is ugly, however, some people (e.g. my boss) assists that... sometimes you have to surrender.Hydraulic
In my opinion, the construct if (5 ==a) {...} is ugly, ugly, ugly, and it is useless against mistakes such as if (i = j) {...}. BTW, I did not downvote.Professorate
L
0

Yes, it is based on the zero/non-zero value which a is assigned. To some people (myself included) it is also considered bad practice to have expressions with side-effects in your code, so the mentioned code fragment would preferably be written as something like

a = 5;
...
if (a != 0) {
    ...
}
Lenlena answered 24/7, 2011 at 14:45 Comment(1)
i think it's fine if it's if (int a=foo()) { ... } ... if-scoped assignment.Pygidium
S
0

In more modern usage, you may sometimes see this pattern used to handle optionals:

std::optional x = ...;
if (auto v = x) {
  // Block only executes if x contained a value, accessible as *v
}
Swore answered 1/6, 2020 at 22:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.