Mixing bitwise and relational operators in the same full expression can be a sign of a logic error in the expression where a logical operator is usually the intended operator. Do not use the bitwise AND (&), bitwise OR (|), or bitwise XOR (^) operators with an operand of type _Bool, or the result of a relational-expression or equality-expression. If the bitwise operator is intended, it should be indicated with use of a parenthesized expression.

Noncompliant Code Example

In this noncompliant code example, a bitwise & operator is used with the results of two equality-expressions:

if (getuid() == 0 & getgid() == 0) { 
  /* ... */ 
} 

Compliant Solution

This compliant solution uses the && operator for the logical operation within the conditional expression:

if (getuid() == 0 && getgid() == 0) {
  /* ... */
}

Risk Assessment

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXP46-C

Low

Likely

Low

P9

L2

Automated Detection

Tool

Version

Checker

Description

Astrée
24.04
inappropriate-boolSupported indirectly via MISRA C:2012 Rule 10.1
Axivion Bauhaus Suite

7.2.0

CertC-EXP46
CodeSonar
8.1p0
LANG.TYPE.IOTInappropriate operand type

Coverity

2017.07

CONSTANT_EXPRESSION_RESULT

Partially implemented

Cppcheck
1.66
cert.pyDetected by the addon cert.py
Helix QAC

2024.1

C3344, C4502

C++3709


Klocwork
2024.1
MISRA.LOGIC.OPERATOR.NOT_BOOL
LDRA tool suite
9.7.1
136 SFully Implemented
Parasoft C/C++test
2023.1

CERT_C-EXP46-b

Expressions that are effectively Boolean should not be used as operands to operators other than (&&, ||, !, =, ==, !=, ?:)

PC-lint Plus

1.4

514

Fully supported

Polyspace Bug Finder

R2023b

CERT C: Rule EXP46-C

Checks for bitwise operations on boolean operands (rule fully covered)

PVS-Studio

7.30

V564, V1015

RuleChecker

24.04

inappropriate-boolSupported indirectly via MISRA C:2012 Rule 10.1

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

ISO/IEC TR 24772:2013Likely Incorrect Expression [KOA]Prior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11CWE-480, Use of incorrect operator2017-07-05: CERT: Rule subset of CWE
CWE 2.11CWE-5692017-07-06: CERT: Rule subset of CWE

CERT-CWE Mapping Notes

Key here for mapping notes

CWE-480 and EXP46-C

Intersection( EXP45-C, EXP46-C) = Ø

CWE-480 = Union( EXP46-C, list) where list =

  • Usage of incorrect operator besides s/&/&&/ or s/|/||/

Bibliography

[Hatton 1995]Section 2.7.2, "Errors of Omission and Addition"



10 Comments

  1. Is this really CWE 480?

    1. It doesn't look like CWE-480 to me. It seems closer to one of CWE-570: Expression is Always False, CWE-768: Incorrect Short Circuit Evaluation, or perhaps CWE-682: Incorrect Calculation. Although none of them looks like a perfect fit.

  2. It seems to me that this is more recommending against using bitwise operations when logical operations are expected.  There's nothing inherently wrong with using bitwise operations in conditionals when it's appropriate, right?  Eg)

    unsigned int a = SOME_VALUE;
    unsigned int b = SOME_VALUE;
     
    if ((a & b) == SOME_VALUE) {
      /* This is acceptable */
    }
    1. No, there is isn't.  It is interesting that Coverity has check for this, although the description suggests it is prone to false positives.

      As stated, this recommendation is clearly too strict.  One option is to send this to the void; the other is to make it more "informational"; a third is to more narrowly define the set of conditions under which this is an error.   

      1. EXP17-C. Do not perform bitwise operations in conditional expressions

        I'll vote for the third, although I'm not sure we can completely enumerate the error conditions. One obvious error condition is to use bitwise ops on inequalities:

        x = a & (b == 0); // should be &&

        On second thought, I'd prefer making this informative, and creating a rule that enumerates the error conditions.

        1. I think the bitwise ops on inequalities could be summed up better as not performing bitwise operations on Boolean operands, since that's most likely to be an error in any situation, regardless of how you get the Boolean operand. That strikes me as possibly being strong enough to make a rule out of.

          1. so if I understand you correctly, the noncompliant example in this recommendation would be compliant under this rule?

            1. No, it would still be noncompliant because geteuid() == 0 would be evaluated first (to a Boolean), which would then be bitwise ANDed with the result of calling getuid().

              1. so in C parlance, I think we would write "one of the operands is of type _Bool or the result of a relational-expression or equality-expression."

                I don't see anywhere in the standard where it says these expressions return a Boolean.  They actually say: 

                Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int.

                All that being said, sounds like a plan. Do you want to promote to a rule and make these changes?

                 

                 

                1. You're correct, they do return an int, which I hadn't noticed before (this is a difference between C and C++). I'll work on turning this into a rule.