Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PHP "short-circuit" logical evaluation...

Status
Not open for further replies.

shadedecho

Programmer
Oct 4, 2002
336
US
OK, my question is two fold:

1. Is there a way to force PHP to disable its normal "short-circuit" evaluation of logical conditionals (ie, x1 || x2 || x3 stops evaluating immediately if it finds a "true")? Can this disabling be done inline (for a particular script or even for a particular part of a script, so as to not affect the performance of other parts, while still giving me the more necessary behavior in a specific spot) instead of globally across the whole distribution?

2. If there is not a way to force PHP to behave differently, then what I need is to find the logical equivalent of || using only "xor" and "!". Why, you ask? because I need the BEHAVIOR of "||" but without the "short-circut", and "xor" and "!" by definition are NOT "short-circuit", meaning they both HAVE TO evaluate the expression to the right of them, no matter what.

the logical table would be:

Code:
 a    b  |  a || b  |  a ^ b  |  ?????  |
___  ___ | ________ | _______ | _______ |
 0    0  |     0    |    0    |    0    |
 0    1  |     1    |    1    |    1    |
 1    0  |     1    |    1    |    1    |
 1    1  |     1    |    0    |    1    |

any thoughts?
 
I follow you, I don't like the IP Stack example though, because to me that's the reverse, where of course an optimized logical version is never going to be enough to do bitwise operations... but effectively, what I hear you saying is... (though obviouslly differently implemented)..

if ((A & B) != 0) then
A && B = 1
else
A && B = 0
end if


Which as you can see, Knowing the value of A && B tells us very little about the value of A & B.

-Rob
 
skiflyer:
The applicability of my example isn't a function of the return of the operator. Don't be fooled by whether the last consideration is whether the end result is zero or non-zero. And don't be distracted by any considerations of optimization -- forget about optimizations for a minute and assume that all logical operators will fetch both operands all the time.

The reason you cannot use logical operators in the IP stack example is because the logical operators would treat each 32-bit number as a single bit. As such, the logical operators could never determine accurately whether a packet was bound for the local network or not. It is the bit-field itself that is important, not whether the value is zero or not.

The bitwise operators treat the values as three ordered sets of 32 bits each, and operate on those bits individually. This is why it's called a network mask. You use it as a bit-pattern to define the extent of the local network. Want the best answers? Ask the best questions: TANSTAAFL!
 
Of course, I understand that example, and the problem of applying a "pure" logical operator when what you want is a bit mask... what I'm confused on, is the opposite... I'm not finding a problem using a bit mask when what I want is a "pure" logical operator (true false only). Am I incorrect in saying

Code:
if ((A & B) != 0) then
  A && B = 1
else
  A && B = 0
end if

Will always return the same function result as A && B (assuming 0 and 1 are the values of True False)... excepting side effects of the statements A and B of course.


This has been enlightening as to why systems use a 0 non-zero rather than a 0,1 setup for True False... I thank you for all the time and discussion.

-Rob
 
You're half-right.

From (A & B) != 0, you can infer A && B = 1.

However, you cannot infer from (A & B) == 0 that (A && B) == 0. Take the example that A = 1 and B = 2. (A & B) will equal 0, because there is no bit turned on in the same place in both values. However, (A && B) will equal 1, because both values are non-zero. Want the best answers? Ask the best questions: TANSTAAFL!
 
OK, so to my question I posed in my last post, which was that the $c === true test (when $c was set equal to the result of a logical operation, such as || or &&) was not correct.

Upon further investigation, I've determined this is in fact because the result of a || (or &&) operation is by default a "int" type, not a "bool" type. I determined this by doing

Code:
$a = true;
$b = false;

if (is_int($a || $b)) echo "it's an Integer!";

if (is_bool($a || $b)) echo "it's a Boolean!";

prints out:

it's an Integer!

if you cast the ($a || $b) operation to bool with (bool)($a || $b), then all works fine, including the $c === true test mentioned before.

if you do is_array(array("blah","blah2")) that will return true, so will is_array($a = array("blah","blah2")). is_double(3/5) will return true. So all those other mathematical equations, assigments, etc result in the correct type, but is_bool($a || $b) does not. WHY?

Doesn't it make sense that for a boolean operation, like logical || or &&, the resultant type WOULD BE BOOLEAN? why is it int? Any thoughts?
 
I'm running 4.3.1 on Linux, and I get "It's a Boolean!!" from your script. When I change the operators from "||" to "|", then I get "It's an Integer!".

This seems like intuitively correct behavior to me.

I would guess you're running an older version of PHP, and someone asked the authors that very question. They then fixed it. Want the best answers? Ask the best questions: TANSTAAFL!
 
sleipnir214, did some digging through the old bug databases, and found this:

Code:
[URL unfurl="true"]http://bugs.php.net/bug.php?id=12245[/URL]

you're right, thanks again!
 
would ya believe it, this dinosaur is still running 4.0.6! :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top