can you do if((myptr) && (myptr->IsGreen()) without blowing up?

Discussion in 'C++' started by Angus, Jun 20, 2008.

  1. Angus

    Angus Guest

    If I need to check if a pointer is valid I usually do a if(ptr) check
    first.

    But I have seen code such as this:

    if((myptr) && (myptr->IsGreen())

    Is this valid?

    Is it because evaluation is from left to right so that the if(ptr) bit
    is evaluated first. Then only if pointer is valid is right function
    called?
    Angus, Jun 20, 2008
    #1
    1. Advertising

  2. Angus

    peter koch Guest

    On 20 Jun., 18:20, Angus <> wrote:
    > If I need to check if a pointer is valid I usually do a if(ptr) check
    > first.
    >
    > But I have seen code such as this:
    >
    > if((myptr) && (myptr->IsGreen())
    >
    > Is this valid?


    Yes, this is guaranteed to work.
    >
    > Is it because evaluation is from left to right so that the if(ptr) bit
    > is evaluated first.  Then only if pointer is valid is right function
    > called?


    This is what is required in the standard, and all compilers adhere to
    this requirement that dates back to C.

    I would avoid the pointers and clarify by writing: if (myptr != 0 &&
    myptr->IsGreen()), but this is a personal choice.

    /Peter
    peter koch, Jun 20, 2008
    #2
    1. Advertising

  3. Angus

    Kai-Uwe Bux Guest

    Angus wrote:

    > If I need to check if a pointer is valid I usually do a if(ptr) check
    > first.
    >
    > But I have seen code such as this:
    >
    > if((myptr) && (myptr->IsGreen())
    >
    > Is this valid?


    Yes.

    > Is it because evaluation is from left to right so that the if(ptr) bit
    > is evaluated first. Then only if pointer is valid is right function
    > called?


    The formal reason is the guarantee in [5.14/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.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jun 20, 2008
    #3
  4. Angus

    Jim Langston Guest

    "Kai-Uwe Bux" <> wrote in message
    news:g3glp3$43d$...
    > Angus wrote:
    >
    >> If I need to check if a pointer is valid I usually do a if(ptr) check
    >> first.
    >>
    >> But I have seen code such as this:
    >>
    >> if((myptr) && (myptr->IsGreen())
    >>
    >> Is this valid?

    >
    > Yes.
    >
    >> Is it because evaluation is from left to right so that the if(ptr) bit
    >> is evaluated first. Then only if pointer is valid is right function
    >> called?

    >
    > The formal reason is the guarantee in [5.14/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.


    As a note, this is sometimes refered to as "short circuiting". It will also
    work with ||
    if ( cond1 || cond2 )

    cond2 will only be evaluated if cond1 is false.
    Jim Langston, Jun 20, 2008
    #4
  5. Angus

    Guest

    On 20 Jun, 18:04, "Jim Langston" <> wrote:
    > "Kai-Uwe Bux" <> wrote in message
    >
    > news:g3glp3$43d$...
    > > Angus wrote:

    >
    > >> If I need to check if a pointer is valid I usually do a if(ptr) check
    > >> first.

    >
    > >> But I have seen code such as this:

    >
    > >> if((myptr) && (myptr->IsGreen())

    >
    > >> Is this valid?

    >
    > > Yes.

    >
    > >> Is it because evaluation is from left to right so that the if(ptr) bit
    > >> is evaluated first.  Then only if pointer is valid is right function
    > >> called?

    >
    > > The formal reason is the guarantee in [5.14/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.

    >
    > As a note, this is sometimes refered to as "short circuiting".  It will also
    > work with ||
    > if ( cond1 || cond2 )
    >
    > cond2 will only be evaluated if cond1 is false.


    Note however that this is a special feature of the operators && and
    ||. If you do something like:

    x = a() + b();

    there is no guarantee which of a and b will be called first.
    , Jun 20, 2008
    #5
  6. Angus

    red floyd Guest

    wrote:
    > On 20 Jun, 18:04, "Jim Langston" <> wrote:
    >> "Kai-Uwe Bux" <> wrote in message
    >>
    >> news:g3glp3$43d$...
    >>> Angus wrote:
    >>>> If I need to check if a pointer is valid I usually do a if(ptr) check
    >>>> first.
    >>>> But I have seen code such as this:
    >>>> if((myptr) && (myptr->IsGreen())
    >>>> Is this valid?
    >>> Yes.
    >>>> Is it because evaluation is from left to right so that the if(ptr) bit
    >>>> is evaluated first. Then only if pointer is valid is right function
    >>>> called?
    >>> The formal reason is the guarantee in [5.14/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.

    >> As a note, this is sometimes refered to as "short circuiting". It will also
    >> work with ||
    >> if ( cond1 || cond2 )
    >>
    >> cond2 will only be evaluated if cond1 is false.

    >
    > Note however that this is a special feature of the operators && and
    > ||. If you do something like:
    >
    > x = a() + b();
    >
    > there is no guarantee which of a and b will be called first.


    Also, if operator&&() or operator||() is overloaded, there is also no
    such guarantee.
    red floyd, Jun 20, 2008
    #6
  7. Angus

    Noah Roberts Guest

    red floyd wrote:

    > Also, if operator&&() or operator||() is overloaded, there is also no
    > such guarantee.


    Only criminals and madmen implement them otherwise.
    Noah Roberts, Jun 20, 2008
    #7
  8. Angus

    Greg Herlihy Guest

    On Jun 20, 3:08 pm, Noah Roberts <> wrote:
    > red floyd wrote:
    > > Also, if operator&&() or operator||() is overloaded, there is also no
    > > such guarantee.

    >
    > Only criminals and madmen implement them otherwise.


    But there is no way to specify the order in which the operands will be
    evaluated when implementing an overloaded operator&&(), operator&&()
    or (for that matter) operator,(). For this reason, overloading any one
    of these three operators is seldom a good idea.

    Greg
    Greg Herlihy, Jun 21, 2008
    #8
  9. Angus

    Greg Herlihy Guest

    On Jun 20, 3:08 pm, Noah Roberts <> wrote:
    > red floyd wrote:
    > > Also, if operator&&() or operator||() is overloaded, there is also no
    > > such guarantee.

    > Only criminals and madmen implement them otherwise.


    You must mean that only criminals and madmen implement these overloads
    -at all-.

    Because there is no way for anyone to specify the order in which the
    operands will be
    evaluated when implementing an overloaded operator&&(), operator||()
    or (for that matter) operator,(). For this reason, overloading any
    one
    of these three operators is seldom a good idea.

    Greg
    Greg Herlihy, Jun 21, 2008
    #9
  10. peter koch wrote:
    >> if((myptr) && (myptr->IsGreen())
    >>
    >> Is this valid?

    >
    > Yes, this is guaranteed to work.


    Nitpicking, but it's guaranteed to work only if myptr actually points
    to an object of the proper type. If it points to garbage (which could be
    achieved, for example, through reinterpret_cast), obviously UB will
    happen. But yeah, this is just nitpicking.
    Juha Nieminen, Jun 21, 2008
    #10
  11. Angus

    peter koch Guest

    On 21 Jun., 05:00, Greg Herlihy <> wrote:
    > On Jun 20, 3:08 pm, Noah Roberts <> wrote:
    >
    > > red floyd wrote:
    > > > Also, if operator&&() or operator||() is overloaded, there is also no
    > > > such guarantee.

    > > Only criminals and madmen implement them otherwise.

    >
    > You must mean that only criminals and madmen implement these overloads
    > -at all-.
    >
    > Because there is no way for anyone to specify the order in which the
    > operands will be
    > evaluated when implementing an overloaded operator&&(), operator||()
    > or (for that matter) operator,(). For this reason, overloading any
    > one
    > of these three operators is seldom a good idea.
    >
    > Greg


    Right. But that does not exclude the rare occasions where overloading
    is fine. For one example, you could imagine overloading those
    operators when you implement fuzzy logic. In that case, you would of
    course be aware that both operands would be overloaded.

    /Peter
    peter koch, Jun 21, 2008
    #11
  12. red floyd wrote:
    > Also, if operator&&() or operator||() is overloaded, there is also no
    > such guarantee.


    The standard guarantees operator priorities (even if the operators are
    overloaded) but it doesn't guarantee the order in which the terms are
    evaluated for overloaded operators? Why is that?

    That is, if you do something like "a && b + c", where both operator&&
    and operator+ have been overloaded for the used type, it's, AFAIK,
    guaranteed that operator+ will be called with b and c as parameters and
    then operator&& with a and the result of that operator+ call as
    parameters. However, whether the result of a or b+c is evaluated first
    is not guaranteed? Why?

    Why does it make sense to guarantee priorities even for overloaded
    operators, but not the same evaluation rules?
    Juha Nieminen, Jun 21, 2008
    #12
  13. > if((myptr) && (myptr->IsGreen())
    >
    > Is this valid?


    Generally, it is valid. However, I have seen compiler options such as
    "full evaluations of binary expressions". This option means that all
    expressions are evaluated, even though the result is known without
    calculating all of them.

    My 2 cents
    Yakov Gerlovin, Jun 21, 2008
    #13
  14. Yakov Gerlovin wrote:
    >> if((myptr) && (myptr->IsGreen())
    >>
    >> Is this valid?

    >
    > Generally, it is valid. However, I have seen compiler options such as
    > "full evaluations of binary expressions". This option means that all
    > expressions are evaluated, even though the result is known without
    > calculating all of them.


    I really can't understand the reason for a compiler to offer such an
    option. Not only does it break the standard, it probably breaks a lot of
    code, and potentially makes code very inefficient. It's also completely
    useless because if at some point in your code you really need to
    evaluate both expressions, you can do that explicitly:

    bool ret1 = expression1();
    bool ret2 = expression2();
    if(ret1 && ret2) ...

    which also makes it quite clearer that evaluating both expressions is
    intended, instead of being a hidden feature of an obscure compiler option.

    That kind of option just doesn't make any sense whatsoever.
    Juha Nieminen, Jun 21, 2008
    #14
  15. Angus

    James Kanze Guest

    On Jun 21, 11:12 am, Juha Nieminen <> wrote:
    > red floyd wrote:
    > > Also, if operator&&() or operator||() is overloaded, there is also no
    > > such guarantee.


    > The standard guarantees operator priorities (even if the
    > operators are overloaded) but it doesn't guarantee the order
    > in which the terms are evaluated for overloaded operators? Why
    > is that?


    > That is, if you do something like "a && b + c", where both
    > operator&& and operator+ have been overloaded for the used
    > type, it's, AFAIK, guaranteed that operator+ will be called
    > with b and c as parameters and then operator&& with a and the
    > result of that operator+ call as parameters. However, whether
    > the result of a or b+c is evaluated first is not guaranteed?
    > Why?


    Because what is actually guaranteed is that the second operand
    won't even be evaluated if the truth value of the expression can
    be determined by the first. But there is no way to call a user
    defined binary operator without first having evaluated both
    operands.

    > Why does it make sense to guarantee priorities even for
    > overloaded operators, but not the same evaluation rules?


    Because they would be impossible to specify: you would need to
    call a function with two operands, but not have evaluated the
    second under some undefined conditions (undefined, because
    that's what the overload would define).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 21, 2008
    #15
  16. Angus

    peter koch Guest

    On 21 Jun., 11:37, Yakov Gerlovin <> wrote:
    > > if((myptr) && (myptr->IsGreen())

    >
    > > Is this valid?

    >
    > Generally, it is valid. However, I have seen compiler options such as
    > "full evaluations of binary expressions". This option means that all
    > expressions are evaluated, even though the result is known without
    > calculating all of them.
    >
    > My 2 cents


    I have not, but certainly using such an option makes the behaviour non-
    compliant, and it also would break tons of code in existence. What
    compiler are you talking about?
    I have an understanding for other languages that prefer more freedom
    in evaluating boolean expression - one obvious example is SQL. Also
    Ada will normally guarantee evaluation of both sides. Special
    operators are needed to avoid this (AND THEN resp. OR ELSE). In my
    mind, this is the wrong default for a low-level language (and the
    right one for a highlevel ditto).

    /Peter
    peter koch, Jun 21, 2008
    #16
  17. James Kanze wrote:
    > Because they would be impossible to specify: you would need to
    > call a function with two operands, but not have evaluated the
    > second under some undefined conditions (undefined, because
    > that's what the overload would define).


    Clearly C++ needs some form of lazy evaluation... ;)
    Juha Nieminen, Jun 21, 2008
    #17
  18. Angus

    Noah Roberts Guest

    Greg Herlihy wrote:
    > On Jun 20, 3:08 pm, Noah Roberts <> wrote:
    >> red floyd wrote:
    >>> Also, if operator&&() or operator||() is overloaded, there is also no
    >>> such guarantee.

    >> Only criminals and madmen implement them otherwise.

    >
    > You must mean that only criminals and madmen implement these overloads
    > -at all-.


    No, I just didn't think about it clearly since I never do it.

    I can imagine that you might want to, but I'd think twice about it any
    time I might. Since you can't write it to have the same behavior, you
    can't really call templates that use it. Probably better to explicitly
    use some function call that you then override for basic types so you can
    use your new templates with old types.
    Noah Roberts, Jun 23, 2008
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ashish
    Replies:
    1
    Views:
    533
    bruce barker
    Nov 17, 2003
  2. rao
    Replies:
    1
    Views:
    3,273
  3. asj
    Replies:
    138
    Views:
    2,405
    William Brogden
    Sep 1, 2003
  4. Replies:
    2
    Views:
    361
  5. John Nagle
    Replies:
    3
    Views:
    629
    Waldemar Osuch
    Nov 10, 2007
Loading...

Share This Page