开发者

In C++ what causes an assignment to evaluate as true or false when used in a control structure?

So can someone help me grasp all the (or most of the relevant) situations of an assignment inside something like an if(...) or while(...), etc?

What I mean is like:

if(a = b)

or

while(a = &c)
{
}

etc...

When will it evaluate as true, and when will it evaluate as false? Does this change at all depending on the types used in the assignment?开发者_运维问答 What about when there are pointers involved?

Thanks.


In C++ an attribution evaluates to the value being attributed:

int c = 5; // evaluates to 5, as you can see if you print it out
float pi = CalculatePi(); // evaluates to the result
                          // of the call to the CalculatePi function

So, you statements:

if (a = b) { }
while (a = &c) { }

are roughly equivalent to:

a = b
if (b) { }
a = &c
while (&c) { }

which are the same as

a = b
if (a) { }
a = &c
while (a) { }

And what about those if (a) etc when they are not booleans? Well, if they are integers, 0 is false, the rest is true. This (one "zero" value -> false, the rest -> true) usually holds, but you should really refer to a C++ reference to be sure (however note that writting if (a == 0) is not much more difficult than if (!a), being much simpler to the reader).

Anyways, you should always avoid side-effects that obscure your code.

You should never need to do if (a = b): you can achieve exactly the same thing in other ways that are more clear and that won't look like a mistake (if I read a code like if (a = b) the first thing that comes to my mind is that the developper who wrote that made a mistake; the second, if I triple-check that it is correct, is that I hate him! :-)

Good luck


An assignment "operation" also returns a value. It is the type and value of the expression. If handled by an if type statement:

  • while (expr)
  • do ... until (expr)
  • if (expr)
  • or the ternary operator (expr) ? (true value) : false value

expr is evaluated. If it is nonzero, it is true. If zero, it is false.


The return type of the assignment is the left hand value, it's what allows statements like a = b = c to compile. In your example:

while(a = &c)
{
}

Returns true when "a" is true, after it has been assigned the value of &c.


In both examples you listed, inside the parentheses is evaluated to true if a is non-zero after the assignment.

In a more common case, you compare a variable with a constant, to avoid this problem, some coding standards require that you write the constant first.

if (A_CONSTANT = var_a)

this would be caught by the compiler, whereas,

if (var_a = A_CONSTANT)

won't.


An assignment statement evaluates to the new value of the variable assigned to (barring bizarre overloads of operator=). If the assignment happens in a boolean context it will then depend on the type of that value how it is treated. If the value is a bool, it is of course treated as a bool. If the value is a numeric value, a non-zero value is treated as true. If the value is a pointer, a non-NULL value is treated as true. If it is a object, the compiler will attempt to convert it to a boolean value (e.g. operator bool). If that is not possible, the compiler will attempt to convert the object to a value that is convertible to bool (e.g. a pointer type, or a numeric type such as int). Finally, if there is no conversion to be performed, or there are multiple possible conversions (e.g. the object defines operator int and operator foo*), the code will fail to compile.


if (a = b)
    ...

is the shorthand for:

a = b;
if (a != 0)
    ...

In a while statement, assignment within the condition enables the DRY principle:

while (a = b)
{
    ...
}

is shorthand for (notice how I had to replicate the assignment so that it is done right before the condition check):

a = b;
while (a != 0)
{
    ...
    a = b;
}

That said, one classic issue with code like this is knowing whether the code intended to do an assignment or if the code forget an '=' when the intent was to write '==' (i.e. should that have been while (a == b).

Because of this, you should never write just a plain assignment (gcc will issue a warning such as "suggest parentheses around assignment used as truth value"). If you want to use assignment in a control structure, you should always surround it with extra parentheses and explicitly add the not-equal:

if ((a = b) != 0)
    ...

while ((a = b) != 0)
    ...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜