0
\$\begingroup\$
// Hardware sets a RIS interrupt status bit    
if(GPIO_PORTE_RIS_R & 0x10)   
{
   // Software acknowledges the flag and clears the read-only RIS bit by setting ICR
   GPIO_PORTE_ICR_R = 0x10;  
   // something useful 
}

The above code should be self explanatory - the hardware flags a register bit, the software clears it. What I don't understand is why the code uses GPIO_PORTE_RIS_R & 0x10 to compare register value instead of GPIO_PORTE_RIS_R == 0x10.

== operation would probably equivalent to a CMP followed by a BEQ or BNE in assembly, or it can be SUBS with a branch by flagging the Z (Zero) bit. Either way using == is straightforward and intuitive - I don't have to convert values into binaries to predict an outcome.

But with & and say if GPIO_PORTE_RIS_R = 0x20, the logical bitwise AND operation between 0x20 & 0x10 or 0010.0000 & 0001.0000 in binary will result in 0000.0000 or a false. And imagine if GPIO_PORTE_RIS_R = 0x30 or 0011.0000 in binary, the condition statement would return true even if the two operands (0x30 & 0x10) don't equate. It seems as if the & operator checks if a register contains a value (or vice versa, a register is subset of a value). It's just confusing to think or use.

In what situation should I use & instead of == and why? And is there a simpler way to think about it?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ One more thing: in C, logical AND is && and bitwise AND is &. \$\endgroup\$
    – The Photon
    Aug 12, 2020 at 5:45

2 Answers 2

5
\$\begingroup\$

When you write if REG & 0x10 you're checking whether bit 4 of the register REG is set.

If the value of REG is 0x30, then bit 4 is set, and you should do the thing you want to do when bit 4 is set.

If the value of the REG is 0x20 then bit 4 isn't set, so you shouldn't do the thing you want to do when bit 4 is set.

And that's exactly the behavior you get if you write if REG & 0x10 {...}.

What I don't understand is why the code uses GPIO_PORTE_RIS_R & 0x10 to compare register value instead of GPIO_PORTE_RIS_R == 0x10.

If you used == then if bit 4 was set, but some other bit was also set, then you wouldn't do whatever it is you want to do when bit 4 is set.

But since you want to do that thing when bit 4 is set regardless of what other bits are set, then this is wrong.

\$\endgroup\$
3
\$\begingroup\$

Rule of thumb:

  • Use & when you care about individual bits and only those bits.
  • Use == when you care about the whole value of a variable.

You can of course also use & to check a whole variable against a mask, and in that case it is almost equivalent to ==. Except & returns either zero or a non-zero value, while == always returns either 0 or 1.


Advanced differences:
Both operators are equivalent when it comes to order of evaluation - it is unspecified. They are equivalent when it comes to implicit type promotions, except the result of & is always of the type of the (promoted) operands, while the result of == is always int.

Example (32 bit computer):

uint64_t a;
uint64_t b;
printf("%zu\n", sizeof (a & b));  // prints 8
printf("%zu\n", sizeof (a == b)); // prints 4
\$\endgroup\$
1
  • \$\begingroup\$ For C++ users: == returns a bool. \$\endgroup\$
    – Arsenal
    Aug 12, 2020 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.