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

A

Angus

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?
 
P

peter koch

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
 
K

Kai-Uwe Bux

Angus said:
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
 
J

Jim Langston

Kai-Uwe Bux said:
Angus said:
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.
 
G

gw7rib

Angus wrote:
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.
 
R

red floyd

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

Greg Herlihy

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
 
G

Greg Herlihy

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
 
J

Juha Nieminen

peter said:
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.
 
P

peter koch

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
 
J

Juha Nieminen

red said:
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?
 
Y

Yakov Gerlovin

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
 
J

Juha Nieminen

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

James Kanze

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

peter koch

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
 
J

Juha Nieminen

James said:
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... ;)
 
N

Noah Roberts

Greg said:
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.
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top