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

前端 未结 6 1917
后悔当初
后悔当初 2020-11-29 11:46

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:<

相关标签:
6条回答
  • 2020-11-29 11:48
    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 讨论(0)
  • 2020-11-29 11:49

    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.

    0 讨论(0)
  • 2020-11-29 11:55

    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.

    0 讨论(0)
  • 2020-11-29 12:00

    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.

    0 讨论(0)
  • 2020-11-29 12:03

    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

    0 讨论(0)
  • 2020-11-29 12:03

    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.

    0 讨论(0)
提交回复
热议问题