0

In MSVC 2010 C++ I display x and y as both true and then execute x&=y; resulting in x as false

I cannot repeat in debugger. When I changed to x = x && y; then result is true as expected.

Should I change the code or dig deeper - I am maintaining a large legacy system targeted for multiple compilers and multiple processors?

joemooney
  • 1,467
  • 1
  • 13
  • 17
  • 2
    possible duplicate of [Is there any difference between && and & with bool(s)?](http://stackoverflow.com/questions/6577504/is-there-any-difference-between-and-with-bools) – herohuyongtao Feb 21 '14 at 17:47
  • @herohuyongtao that is not really a dup since the OP is not getting a result consistent with that. – Shafik Yaghmour Feb 21 '14 at 17:48
  • 4
    Can you provide an [SSCCE](http://www.sscce.org/), it would be even better if you could provide a [live example](http://stackoverflow.com/questions/3916000/online-c-compiler-and-evaluator) as well. – Shafik Yaghmour Feb 21 '14 at 17:49
  • it's Just the kind of code you shouldn't write if you take care of maintain ability and readability! – alexbuisson Feb 21 '14 at 17:50

2 Answers2

2

&=is binary AND. && is logical AND.

If both values really are bool then they should work the same. But I suspect that they're not.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • They both are definitely bool. – joemooney Feb 21 '14 at 17:47
  • Then it will _look like_ it is the same (though technically it isn't). `&&` guarantees that the right side is not evaluated if the left side evaluates to `false` (of course that makes no difference in this special case, unless `y` happens to be an _invalid_ object, in which case you'd see a crash trying to access it using operator `&` and only a 50% chance of a crash otherwise). – Damon Feb 21 '14 at 17:56
  • Ok, thanks. I have been beating my head against the wall on this and cannot figure out why I am seeing the bad behavior (but not in the debugger) - there must be a deeper issue. I just wanted to confirm that this ought to be fine and is not considered out-and-out bad practice. – joemooney Feb 21 '14 at 17:59
  • 1
    To elaborate: It is not specified what the values of `true` and `false` are, only how they compare, evaluate, and such (usually, but not necessarily they are 0 and 1, but they could be something different). But whatever they are, they are always the same on the same compiler. So either way, it would "work" the same using logical or binary operators. You should, however, still always use the _correct_ one, not the one that _accidentially_ works as well because some bit pattern is the same. If for no other reason, it won't make people reading your code throw up. – Damon Feb 21 '14 at 18:00
  • Thanks, the problem with maintaining old large systems is to minimize the changes etc. and to be able to provide a sound explanation as to why code changes are really needed. – joemooney Feb 21 '14 at 18:03
  • I will accept this answer and look for a deeper problem - though why changing it to a logical and instead of the binary and it works is troubling because I cannot explain why it would behave differently consistently during testing. – joemooney Feb 21 '14 at 18:11
  • @Damon: C++ N3337 §4.5 `[conv.prom]` /6: "A prvalue of type `bool` can be converted to a prvalue of type `int`, with `false` becoming zero and `true` becoming one." – Mooing Duck Feb 21 '14 at 18:22
  • @MooingDuck: Wrong conclusion. It is well-defined what `true` and `false` can convert to (from), and that they compare different, much like e.g. the null pointer is defined to _convert from_ a zero integer literal. However, the values _per se_ are undefined (and on some exotic architectures, `true` is indeed not equal to 1, even though _converting_ it to an integer will give 1). Again, this is similar to the null pointer, which is _not zero_ on some architectures! However since whatever-it-is evaluates `true` with `operator&` on itself, it still "works" regardless of the actual bit pattern. – Damon Feb 21 '14 at 18:36
-1

bool is not a basic type. Generally, it relies on int or char with 1 as true and 0 as false, but it is not a standard."

If x and y are both bool, bitwise AND (&) and logical AND (&&) will lead to the same result with this implementation. However, MSVC just says that :

!false == true
!true == false

So you may have different results. It's bad design using bitwise operators with booleans. For example, casting an int to a bool will generate a warning C4800 (MSVC). The problem is that the conversion from bool to int is always implicit and you're allowed to use any arithmetic operator on them.

auto s = true + true + true; // = 3
// std::is_same<decltype(s), int>::value is True

Edit : mea culpa

Kiwi
  • 2,698
  • 16
  • 15
  • 1
    `bool` is a basic type – Mooing Duck Feb 21 '14 at 18:23
  • While it requires knowing the rules surrounding it, using `bool` in arithmetic expressions just takes a little getting used to. `int value = (1 + is_doubled) * i;` is perfectly okay (to me, in the sense that I have no preference between reading this or the ternary operator), or even `switch(4 * bool1 + 2 * bool2 + bool3){...}` for handling of multiple different booleans where each combination determines what to do. – SirGuy Feb 21 '14 at 19:28