Order of functions in an IF

L

LSW

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,
 
Z

Zeppe

LSW said:
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
 
S

Sylvester Hesp

Zeppe wrote :
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
 
Z

Zeppe

Sylvester said:
Zeppe wrote :

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
 
V

Victor Bazarov

Zeppe said:
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
 
Z

Zeppe

Victor said:
>
> 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).
>
> 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
 
J

James Kanze

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

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top