-1

I am wondering if this two approaches are equivalent? Is one of them better than the other?

First:

bool x = foo();
bool y = bar();

if(x || y)
{
   //...
}

Second:

if(foo() | bar())
{
   //...
}
Wojteq
  • 1,173
  • 9
  • 23
  • 8
    Your question does not indicate any research effort. – Kiley Naro Oct 19 '11 at 18:11
  • Have you looked at what `||` means and what `|` means? – Oded Oct 19 '11 at 18:12
  • 3
    Actually I think the question is valid. `||` has short circuit evaluation, so modifying his second example to use `||` instead of `|` would give a different result if `bar()` has side effects and foo() returns `false`. – DeCaf Oct 19 '11 at 18:15
  • 1
    This question is not a duplicate of http://stackoverflow.com/questions/35301/what-is-the-diffference-between-the-and-or-operators – David Heffernan Oct 19 '11 at 18:28

7 Answers7

3

http://msdn.microsoft.com/en-us/library/6373h346(v=vs.71).aspx

The conditional-OR operator (||) performs a logical-OR of its bool operands, but only evaluates its second operand if necessary.

http://msdn.microsoft.com/en-us/library/kxszd0kx(v=vs.71).aspx

Binary | operators are predefined for the integral types and bool. For integral types, | computes the bitwise OR of its operands. For bool operands, | computes the logical OR of its operands; that is, the result is false if and only if both its operands are false.

Kiley Naro
  • 1,749
  • 1
  • 14
  • 20
3

These two versions are equivalent. The || operator short-circuits, but | does not. Since you evaluate x and y before testing x || y, that comes to the same as foo() | bar().

Now, if you had compared

foo() | bar()

with

foo() || bar()

then they would be different. However, your prior evaluation into x and y was sufficient to render the two tests equivalent.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

The main difference between | and || is short circuiting, but that doesn't matter here, since your code that uses || already evalates both expressions beforehand, short circuiting is irrelevant here.

Assuming both foo() and bar() return a normal bool, this should be equivalent.

If the return type is different from bool implicit conversions and overload resolution can lead to different results.

If you use hacked bools(AFAIK only achievable with unsafe code) which have an underlying value different from 0 or 1 they can be different too.

With hacked bools we can observe that | has binary semantics, even on bools. I'm not sure if this is specified behavior at the runtime level, or if it's just undefined behavior, and as such might change with different compiler/jitter versions. My implementation with explicit struct layout is certainly undefined behavior, but I'm not sure if other languages can create such bools without such a hack.

void Main()
{
    bool b1 = hackbool(1);
    bool b2 = hackbool(2);
    ((b1 | b2)&b2).Dump();
    ((b1 || b2)&b2).Dump();
}

[StructLayout(LayoutKind.Explicit)]
internal struct Evil
{
    [FieldOffset(0)]public int i;
    [FieldOffset(0)]public bool b;
}

bool hackbool(int i)
{
    Evil e=new Evil();
    e.i=i;
    return e.b;
}
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
1
if(foo() | bar())
{
   //...
}

If you meant foo() || bar(), then, this will be faster than first version in one case. When foo() is true, it won't execute bar() But in case of |, it is equivalent

hungryMind
  • 6,931
  • 4
  • 29
  • 45
0

|| is a conditional-OR (tests boolean values), and | is a bitwise-OR.

0

| is an artihmetic operator. so (in binary) 0101 | 0111 = 0111 (you put a one where either operand has a 1..

|| is a logical operator, if (a||b) { do something } occurs if a or b is true.

They are totally different.

Stephen
  • 3,341
  • 1
  • 22
  • 21
  • No, both can be used for boolean comparisons. See Kileys answer for the correct explanation. – Florian Greinacher Oct 19 '11 at 18:15
  • If you use a |, its going to do the logical or of the two operands and then evaluate whether or not that result is a true or false value. Thats highly inefficent and not a good use of the operator unless your specfically looking for that kind of result. They aren't the same. – Stephen Oct 19 '11 at 18:19
  • Yes, but your answer implies that both do different things. – Florian Greinacher Oct 19 '11 at 18:24
  • if you did (0xFFFF || 0x0000) you would get true. If you did (0xFFFF | 0xFFFF) you would get 0xFFFF. The result is 100% different. Both would evaluate to true as they are non-zero constants but that doesn't make them the same. – Stephen Oct 19 '11 at 18:28
0

|| is also a 'sequence point.' It is possible, for example, that if you coded

if (foo() || bar())
    ....

If foo() returned true, bar() might not even be called because 'if' has all it needs to evalaute teh expression as true. That may or may not be good!

n8wrl
  • 19,439
  • 4
  • 63
  • 103