Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

MISRA.ETYPE.INAPPR.OPERAND.UNOP.2012

MISRA C 2012 Rule 10.1: Operands shall not be of an inappropriate essential type

C90 [Unspecified 23; Implementation 14, 17, 19, 32]

C99 [Undefined 13, 49; Implementation J3.4(2, 5), J3.5(5), J3.9(6)]

Category: Required

Analysis: Decidable, Single Translation Unit

Applies to: C90, C99

Amplification

In the following table a number within a cell indicates where a restriction applies to the use of an essential type as an operand to an operator. These numbers correspond to paragraphs in the Rationale section below and indicate why each restriction is imposed.

Operator Operand Essential type category of arithmetic operand
Boolean character enum signed unsigned floating
[ ] integer 3 4       1
+ (unary)   3 4 5      
- (unary)   3 4 5   8  
+ - either 3   5      
* / either 3 4 5      
% either 3 4 5     1
< > <= >= either 3          
== != either            
! && || any   2 2 2 2 2
<< >> left 3 4 5, 6 6   1
<< >> right 3 4 7 7   1
~ & | ^ any 3 4 5, 6 6   1
?: 1st   2 2 2 2 2
?: 2nd and 3rd            

Under this rule the ++ and -- operators behave the same way as the binary + and - operators.

Other rules place further restrictions on the combination of essential types that may be used within an expression.

Rationale

  1. The use of an expression of essentially floating type for these operands is a constraint violation.
  2. An expression of essentially Boolean type should always be used where an operand is interpreted as a Boolean value.
  3. An operand of essentially Boolean type should not be used where an operand is interpreted as a numeric value.
  4. An operand of essentially character type should not be used where an operand is interpreted as a numeric value. The numeric values of character data are implementation-defined.
  5. An operand of essentially enum type should not be used in an arithmetic operation because an enum object uses an implementation-defined integer type. An operation involving an enum object may therefore yield a result with an unexpected type. Note that an enumeration constant from an anonymous enum has essentially signed type.
  6. Shift and bitwise operations should only be performed on operands of essentially unsigned type. The numeric value resulting from their use on essentially signed types is implementation-defined.
  7. The right hand operand of a shift operator should be of essentially unsigned type to ensure that undefined behaviour does not result from a negative shift.
  8. An operand of essentially unsigned type should not be used as the operand to the unary minus operator, as the signedness of the result is determined by the implemented size of int.

Exception

A non-negative integer constant expression of essentially signed type may be used as the right hand operand to a shift operator.

Example

enum enuma { a1, a2, a3 } ena, enb;  /* Essentially enum<enuma> */
enum { K1 = 1, K2 = 2 };             /* Essentially signed      */

The following examples are non-compliant. The comments refer to the numbered rationale item that results in the non-compliance.

f32a & 2U           /* Rationale 1 - constraint violation                   */
f32a << 2           /* Rationale 1 - constraint violation                   */

cha && bla          /* Rationale 2 - char type used as a Boolean value      */
ena ? a1 : a2       /* Rationale 2 - enum type used as a Boolean value      */
s8a && bla          /* Rationale 2 - signed type used as a Boolean value    */
u8a ? a1 : a2       /* Rationale 2 - unsigned type used as a Boolean value  */
f32a && bla         /* Rationale 2 - floating type used as a Boolean value  */

bla * blb           /* Rationale 3 - Boolean used as a numeric value        */
bla > blb           /* Rationale 3 - Boolean used as a numeric value        */

cha & chb           /* Rationale 4 - char type used as a numeric value      */
cha << 1            /* Rationale 4 - char type used as a numeric value      */

ena--               /* Rationale 5 - enum type used in arithmetic operation */
ena * a1            /* Rationale 5 - enum type used in arithmetic operation */

s8a & 2             /* Rationale 6 - bitwise operation on signed type       */
50 << 3U            /* Rationale 6 - shift operation on signed type         */

u8a << s8a          /* Rationale 7 - shift magnitude uses signed type       */
u8a << -1           /* Rationale 7 - shift magnitude uses signed type       */

-u8a                /* Rationale 8 - unary minus on unsigned type           */

The following example is non-compliant with this rule and also violates Rule 10.3:

ena += a1           /* Rationale 5 - enum type used in arithmetic operation */

The following examples are compliant:

bla && blb
bla ? u8a : u8b

cha - chb
cha > chb

ena > a1
K1 * s8a     /* Compliant as K1 from anonymous enum */

s8a + s16b
-( s8a ) * s8b
s8a > 0
--s16b

u8a + u16b
u8a & 2U

u8a > 0U
u8a << 2U
u8a << 1     /* Compliant by exception              */

f32a + f32b
f32a > 0.0

The following is compliant with this rule but violates Rule 10.2

cha + chb