6

While looking through some code today, I came across an interesting(unecessary?) method for setting a variable: Adding a logical AND to the value.

LED_GRN = (ivLEDGrnSequence & ivLEDSlot) && 1;

I looked around a bit more for some of these occurrences and found them throughout the code, but in different forms:

As an argument for a function:

isoAgCmdHideShow(iObjectID,( (ecu.l & sVar->mask) && 1), (uint8_t *)TxMsg.buf);

In a conditional:

if( (usbQueue.selection & USB_SELECTION_CAN_1) && 1 ) {return TRUE;}

Does this extra logical AND actually change anything about the code, or is it just superfluous? I tried searching for this online, but the closest I found to an answer is Short-Circuit Evaluation which doesn't seem to apply in these situations because short-circuiting a 1 is useless.

In short, what does Logical AND 1 do for variable declaration?

StephenKercher
  • 143
  • 1
  • 7

4 Answers4

7

This appears to be a trick to force any non-zero number to 1, while keeping zeros - alongside a more common !!(expr) idiomatic construct.

The idea is to set LED_GRN to 1 or 0 based on the value of ivLEDGrnSequence & ivLEDSlot.

Other ways to do the same thing are as follows:

LED_GRN = !!(ivLEDGrnSequence & ivLEDSlot);
LED_GRN = (ivLEDGrnSequence & ivLEDSlot) != 0;
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • That makes more sense. Thanks for the alternatives to that approach! edit: Is there any use for it in the conditional, as above? – StephenKercher Jun 29 '18 at 19:04
  • Another way: `LED_GRN = (ivLEDGrnSequence & ivLEDSlot) ? 1 : 0;` – Jim Rhodes Jun 29 '18 at 19:08
  • Or simply: `bool LED_GRN = ivLEDGrnSequence & ivLEDSlot`. – user3386109 Jun 29 '18 at 19:14
  • 1
    @EugeneSh. It should work on modern compilers (certainly when conforming to C11). `bool` or more specifically `_Bool` was a late addition to the language. So out-of-date compilers may display quirky behavior when dealing with `bool`. – user3386109 Jun 29 '18 at 19:24
4

Doing x && 1 produces either 1 or 0, regardless of what non-zero value the left operand evaluates to.

From the C standard:

§6.5.13 Logical AND operator

The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
3

It's converting the result of the bitwise AND to either 0 or 1. The result of the bitwise AND can be 0 or any non-zero number. But after the logical AND, the result can only be 0 or 1.

So the first two examples may be useful. The third example with the if statement is definitely not useful, since if converts the expression to a boolean.

user3386109
  • 34,287
  • 7
  • 49
  • 68
3

The result of logical operation (in this case &&) is either 0 or 1. The result of arithmetic or bitwise operation (& in this case) is 0 or non-0. If we want to convert any non-0 to 1 we perform a logical operation on it. The more common and idiomatic way to accomplish this is the double negation:

LED_GRN = !!(ivLEDGrnSequence & ivLEDSlot);
Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61