Order of functions in an IF

Discussion in 'C++' started by LSW, Jun 8, 2007.

  1. LSW

    LSW Guest

    I've tried googling for the answer to this one, but haven't found anything.

    In the following code snippet

    BOOLEAN SomeValue;
    if(SomeValue && SomeFunc())
    DoSomething;

    If SomeValue is False, will SomeFunc() be evaluated? Or will the
    evaluation stop when a False is encountered in a boolean AND expression?

    If it makes any difference, I'm currently using Turbo C++ 3.0 to develop
    for an embedded system.

    Thanks,
     
    LSW, Jun 8, 2007
    #1
    1. Advertising

  2. LSW

    Zeppe Guest

    LSW wrote:
    > I've tried googling for the answer to this one, but haven't found anything.
    >
    > In the following code snippet
    >
    > BOOLEAN SomeValue;
    > if(SomeValue && SomeFunc())
    > DoSomething;
    >
    > If SomeValue is False, will SomeFunc() be evaluated? Or will the
    > evaluation stop when a False is encountered in a boolean AND expression?


    no, it won't be evaluated. The guaranteed order is left-to-right. For
    the same reason A || B doesn't evaluates B if A is true.

    > If it makes any difference, I'm currently using Turbo C++ 3.0 to develop
    > for an embedded system.


    I don't know if it makes any difference, it shouldn't. This is an old C
    standard rule, so i think every compiler it's compliant on it.

    Regards,

    Zeppe
     
    Zeppe, Jun 8, 2007
    #2
    1. Advertising

  3. Zeppe wrote :
    > LSW wrote:
    >> I've tried googling for the answer to this one, but haven't found anything.
    >>
    >> In the following code snippet
    >>
    >> BOOLEAN SomeValue;
    >> if(SomeValue && SomeFunc())
    >> DoSomething;
    >>
    >> If SomeValue is False, will SomeFunc() be evaluated? Or will the
    >> evaluation stop when a False is encountered in a boolean AND expression?

    >
    > no, it won't be evaluated. The guaranteed order is left-to-right. For the
    > same reason A || B doesn't evaluates B if A is true.


    Note that that guarantee alone doesn't mean that SomeFunc() will not be
    evaluated if SomeValue is false, but yes, the default logical or and
    and expressions do short-circuit :)

    However, if BOOLEAN or the return-value of SomeFunc() were some
    user-defined type with an overloaded operator&&(), it will most
    definitely *not* short-circuit, which is probably a good reason why you
    should not want to overload those operators.

    - Sylvester
     
    Sylvester Hesp, Jun 8, 2007
    #3
  4. LSW

    Zeppe Guest

    Sylvester Hesp wrote:
    > Zeppe wrote :
    >> LSW wrote:
    >>> If SomeValue is False, will SomeFunc() be evaluated? Or will the
    >>> evaluation stop when a False is encountered in a boolean AND expression?

    >>
    >> no, it won't be evaluated. The guaranteed order is left-to-right. For
    >> the same reason A || B doesn't evaluates B if A is true.

    >
    > Note that that guarantee alone doesn't mean that SomeFunc() will not be
    > evaluated if SomeValue is false, but yes, the default logical or and and
    > expressions do short-circuit :)


    Sure. It was an additional information: if one argument is true, the
    other is not evaluated AND the guaranteed order of evaluation is
    left-to-right.

    > However, if BOOLEAN or the return-value of SomeFunc() were some
    > user-defined type with an overloaded operator&&(), it will most
    > definitely *not* short-circuit, which is probably a good reason why you
    > should not want to overload those operators.


    Which is an interesting and not obvious collateral effect. I didn't ever
    think about that, but given that if you overload the operator && you are
    defining a function that will be called with the second argument of &&
    as argument, and being a sequence point before the function call, there
    is no way to redefine such an operator and retain the correct behaviour.

    This is equivalent to say that A && B can not be viewed as
    operator&&(A,B). This is a little bit shocking, frankly! :)

    Regards,

    Zeppe
     
    Zeppe, Jun 8, 2007
    #4
  5. Zeppe wrote:
    > Sylvester Hesp wrote:
    >> However, if BOOLEAN or the return-value of SomeFunc() were some
    >> user-defined type with an overloaded operator&&(), it will most
    >> definitely *not* short-circuit, which is probably a good reason why
    >> you should not want to overload those operators.

    >
    > Which is an interesting and not obvious collateral effect. I didn't
    > ever think about that, but given that if you overload the operator &&
    > you are defining a function that will be called with the second
    > argument of && as argument,


    Actually, both the left-hand side and the right-hand side are the
    operator's _arguments_. They are both evaluated before the function
    is called. The order of evaluation is, of course, unspecified.

    > and being a sequence point before the
    > function call, there is no way to redefine such an operator and
    > retain the correct behaviour.


    :) Under "correct" you mean the "built-in" behaviour, of course.
    The behaviour of the overloaded operator can only be "incorrect" if
    the compiler screws up somehow.

    > This is equivalent to say that A && B can not be viewed as
    > operator&&(A,B). This is a little bit shocking, frankly! :)


    They cannot be that only for non-overloaded variation of &&.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jun 8, 2007
    #5
  6. LSW

    Zeppe Guest

    Victor Bazarov wrote:
    > Zeppe wrote:
    >> Sylvester Hesp wrote:
    >>> However, if BOOLEAN or the return-value of SomeFunc() were some
    >>> user-defined type with an overloaded operator&&(), it will most
    >>> definitely *not* short-circuit, which is probably a good reason why
    >>> you should not want to overload those operators.

    >> Which is an interesting and not obvious collateral effect. I didn't
    >> ever think about that, but given that if you overload the operator &&
    >> you are defining a function that will be called with the second
    >> argument of && as argument,

    >
    > Actually, both the left-hand side and the right-hand side are the
    > operator's _arguments_. They are both evaluated before the function
    > is called. The order of evaluation is, of course, unspecified.


    it depends. If you redefine operator&& as a member argument of the class
    A, A would be the member on which you apply the operator (which, of
    course, is equivalent as considering it as the *this argument of a
    binary operator).

    >> This is equivalent to say that A && B can not be viewed as
    >> operator&&(A,B). This is a little bit shocking, frankly! :)

    >
    > They cannot be that only for non-overloaded variation of &&.


    Fair enough. But I always had this kind of naive idea that the behaviour
    of all the built-in operators could be replicated by user defined
    functions. :)

    Regards,

    Zeppe
     
    Zeppe, Jun 8, 2007
    #6
  7. LSW

    James Kanze Guest

    On Jun 8, 4:59 pm, Zeppe
    <zep_p@.remove.all.this.long.comment.yahoo.it> wrote:
    > Victor Bazarov wrote:
    > > Zeppe wrote:


    > >> Sylvester Hesp wrote:
    > >>> However, if BOOLEAN or the return-value of SomeFunc() were some
    > >>> user-defined type with an overloaded operator&&(), it will most
    > >>> definitely *not* short-circuit, which is probably a good reason why
    > >>> you should not want to overload those operators.
    > >> Which is an interesting and not obvious collateral effect. I didn't
    > >> ever think about that, but given that if you overload the operator &&
    > >> you are defining a function that will be called with the second
    > >> argument of && as argument,


    > > Actually, both the left-hand side and the right-hand side are the
    > > operator's _arguments_. They are both evaluated before the function
    > > is called. The order of evaluation is, of course, unspecified.


    > it depends. If you redefine operator&& as a member argument of the class
    > A, A would be the member on which you apply the operator (which, of
    > course, is equivalent as considering it as the *this argument of a
    > binary operator).


    So? The order of evaluation is still not defined, and both must
    be evaluated.

    > >> This is equivalent to say that A && B can not be viewed as
    > >> operator&&(A,B). This is a little bit shocking, frankly! :)


    > > They cannot be that only for non-overloaded variation of &&.


    > Fair enough. But I always had this kind of naive idea that the behaviour
    > of all the built-in operators could be replicated by user defined
    > functions. :)


    That's not true in a lot of cases. There's no way to make a
    user defined operator require an lvalue, for example. If a, b
    and c are build in types, for example, "(a+b) = c" is illegal;
    if they are class types, however, it's not.

    --
    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 8, 2007
    #7
    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. Soren Kuula
    Replies:
    2
    Views:
    529
    Soren Kuula
    Feb 1, 2004
  2. Bhushit Joshipura
    Replies:
    18
    Views:
    529
    David Harmon
    Jan 19, 2004
  3. Xiangliang Meng
    Replies:
    1
    Views:
    1,652
    Victor Bazarov
    Jun 21, 2004
  4. cspoh
    Replies:
    0
    Views:
    264
    cspoh
    Jul 31, 2003
  5. Stephan Kämper
    Replies:
    2
    Views:
    249
    Stephan Kämper
    Jan 18, 2004
Loading...

Share This Page