Tech Off Thread

18 posts

N/T

Back to Forum: Tech Off
  • User profile image
    Manip

    N/T

  • User profile image
    Rossj

    Manip wrote:
    If you wrote this program in C/C++ or Visual Basic or any of the .net langs you will find that you receive two 'Hello World' message boxes and no 'Woo!'


    Erm. I am confused (and now a bit worried about short circuiting evaluations).  I know for a fact that GCC optimises this and I can't believe that Microsoft's compiler wouldn't.   Does this happen in debug and release?

  • User profile image
    wkempf

    What are you talking about?  The standard for C++ requires the short circuit.  And VC++ 2003 certainly behaves correctly.  I'm certain C# is no different here (though I haven't tested).  I won't venture to guess about VB, though I would be surprised if it were any different.

  • User profile image
    wkempf

    Oh, and short circuiting isn't really about optimizing.  I doubt there is any language spec that would leave this as an optimization (IOW, leave it up to an implementation to decide how to behave here).  Optimizations are optional implementation details that are not allowed to modify the significant behavior of the code.  Short circuiting most certainly drastically modifies the significant behavior, and thus must be specified as always occurs or never occurs and compilers are unable to "optimize" the code beyond that.

  • User profile image
    Rossj

    I'd point out that the line of code

    if ( myLogic() && myLogic() )

    won't compile as C# because you can't apply && to two ints.  If you change myLogic to return bool and then have it return false, the short circuit takes place with C#.

    Edit: Quick google tells me VB.Net does not do short circuit .. but you can use new keywords AndAlso, OrElse in order to get the same effect.

  • User profile image
    Sven Groot

    Rossj wrote:
    Edit: Quick google tells me VB.Net does not do short circuit .. but you can use new keywords AndAlso, OrElse in order to get the same effect.

    Yep. Historically, VB's And and Or do not shortcircuit. For VB.Net 1.0 beta 1, they changed this, but it broke too much existing code so people complained. So now we're stuck with the ugly AndAlso and OrElse operators...

    C, C++, C#, Java, they all shortcircuit.

  • User profile image
    Minh

    Manip wrote:
     If you wrote this program in C/C++ or Visual Basic or any of the .net langs you will find that you receive two 'Hello World' message boxes and no 'Woo!' message box.

    This does not happen with VC++, VC#, but WILL happen with VB.NET (by design as someone else already said)

  • User profile image
    Maurits

    Rossj wrote:
    I'd point out that the line of code
    if ( myLogic() && myLogic() )

    won't compile as C# because you can't apply && to two ints.  If you change myLogic to return bool and then have it return false, the short circuit takes place with C#.


    If memory serves me correctly, if(myLogic()) won't work in Java either... for the same reason, namely, if (...) requires a boolean.

    This breaks things like
    if (ptr)

    but it's REALLY NICE for catching bugs like
    if (i = 1) (instead of if (i == 1))

    On the other hand if (!!ptr) looks kind of silly

  • User profile image
    Maurits

    Mom (thinks in VB-ish):
    If kid.CleanTheDishes() And kid.DoHomework() Then
        we.GoToMovie you.PickMovie()
    End If

    Child (thinks in C-ish)
    if (me->CleanTheDishes() && me->DoHomework())
    {    we->GoToMovie(me->PickMovie());
    } else
    {    me->fool_around();
    }

    boolean CleanTheDishes()
    {    ...
        if (kitchen->Inventory("soap") < dishes->SoapNeeded())
        {    shoppingList->add("soap");
            todo->add("Clean The Dishes");
            return false;
        }
        ...
    }

    Mom:
    If Todo.Contains("Clean The Dishes") Then
        Ask kid, "why didn't you clean the dishes"    
    End If

    Child:
    mom->show(kitchen->Inventory);
    mom->show(shoppingList);

    Mom:
    If kid.Explanation.IsSatisfactory() Then
        Pat kid
    End If

    If Not kid.Homework.IsDone Then
        Ask kid, "why didn't you do your homework"
    End If

    Child:
    if (mom->makes_no_sense())
    {    mom->explain("Because && short-circuits");
        mom->explain("See, doing homework is just a < i >side effect< /i >");
        mom->explain("I already knew that !we->GoToMovie(...)");
    }

    Mom:
    kid.GetSupper = False
    kid.SendToRoom

    Child:
    while (me->in_room)
    {    me->grumble("She just doesn't understand...");
    }

  • User profile image
    Jorgie

    ok, I have been jumping between languages too much lately..

    Is C# the one that uses && for for short-circuit and & for non-shor-circuit? or Is that javascript?

    Jorgie

  • User profile image
    Sven Groot

    From the MSDN docs on C++:

    Operator Description
    && The logical-AND operator produces the value 1 if both operands have nonzero values. If either operand is equal to 0, the result is 0. If the first operand of a logical-AND operation is equal to 0, the second operand is not evaluated.
    || The logical-OR operator performs an inclusive-OR operation on its operands. The result is 0 if both operands have 0 values. If either operand has a nonzero value, the result is 1. If the first operand of a logical-OR operation has a nonzero value, the second operand is not evaluated.

    From C#:
    The conditional-AND operator (&&) performs a logical-AND of its bool operands, but only evaluates its second operand if necessary.
    The conditional-OR operator (||) performs a logical-OR of its bool operands, but only evaluates its second operand if necessary.
    Binary & operators are predefined for the integral types and bool. For integral types, & computes the bitwise AND of its operands. For bool operands, & computes the logical AND of its operands; that is, the result is true if and only if both its operands are true.
    (this means that yes, in C# && short-circuits while & doesn't (similar for |). In C(++) this is also the case, not by design but as a side-effect of the way integers are coerced to boolean values)

    For completeness
    From VB.NET:
    The operators AndAlso and OrElse are only defined on the type Boolean and short-circuit; that is, in certain situations, the second operand will not be evaluated at run time.

  • User profile image
    Jorgie

    "Binary & operators are predefined for the integral types and bool. For integral types, & computes the bitwise AND of its operands. For bool operands, & computes the logical AND of its operands; that is, the result is true if and only if both its operands are true.
    (this means that yes, in C# && short-circuits while & doesn't (similar for |). In C(++) this is also the case, not by design but as a side-effect of the way integers are coerced to boolean values)"

    Thank you! That is what I thought!

    Jorgie

  • User profile image
    Maurits

    But don't get in the habit of using & this way - you might get surprising results.

    For example,

    (bool)((int) 10 & (int) 5) != (bool) 10 & (bool) 5

    The LHS is false, the RHS is true.

  • User profile image
    Maurits

    && is logical and-ing
    & is bitwise and-ing

    true && true == true
    true && false == false
    false && true == false
    false && false == false

    12 & 5 == 1100b & 0101b == 0100b == 4

    Not especially fast or useful, except for unsetting bits in a bit field


    EDIT: duh 1100b is 12 not 10

  • User profile image
    ScanIAm

    I have always been under the impression that when evaluating:

    if(x && y)

    it is undefined whether y will be evaluated in the case that x is false.  Because of this, it is a good idea to simply not do this.

    It never ceases to amaze me how often people will code a complicated algorithm in a few lines.  The compiler/jit will break it apart and optimize it, so why not make it readable and obvious?

    (BTW, I used to write in x86 ASM, so I understand that there was a day when short and sweet was better...that day was 15+ years ago).

  • User profile image
    Sven Groot

    ScanIAm wrote:

    I have always been under the impression that when evaluating:

    if(x && y)

    it is undefined whether y will be evaluated in the case that x is false.


    That is not true. From the ISO C++ standard:

    5.14 Logical AND operator
      logical-and-expression:
        inclusive-or-expression
        logical-and-expression && inclusive-or-expression
     
    1 The && operator groups left-to-right. The operands are both implicitly converted to type bool (clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

    And from the ECMA C# standard:
    14.11 Conditional logical operators
    The && and || operators are called the conditional logical operators. They are also called the "shortcircuiting" logical operators.
    conditional-and-expression:
      inclusive-or-expression
      conditional-and-expression && inclusive-or-expression
    conditional-or-expression:
      conditional-and-expression
      conditional-or-expression || conditional-and-expression
    The && and || operators are conditional versions of the & and | operators:
    • The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is true.
    • The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is
    false.

  • User profile image
    JKelley

    IIRC the standard for C++ got changed at some point.  Possibly between VC++ 5.0 and 6.0?  Early on on one of the projects I worked on we had a terrible time with people putting function calls on the right hand side of a && that depended on the left hand side.  Since none of us knew for sure what the standard was we couldn't rule it out as a reason why we had things crashing some times.  (Sure we had plenty of other reasons why the system crashed but why have something else to worry about right?)

    Now that things are definitively standardized it seems like good coding practice to break those things apart and nest them properly.  The added readability and explicit dependence described is worth it.  Saving an extra 2 lines of code seems like being lazy.

  • User profile image
    Sven Groot

    JKelley wrote:
    IIRC the standard for C++ got changed at some point.  Possibly between VC++ 5.0 and 6.0?

    Actually, the official first edition of the C++ standard was finalised in 1998, after Visual C++ 6 was released.

    The text I quoted comes from the second edition, which was accepted as a standard in 2003.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.