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.ASSIGN.2012

Assignment to an object of a narrower essential type or a different essential type category.

MISRA C 2012 Rule 10.3: The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category

C90 [Undefined 15; Implementation 16], C99 [Undefined 15, 16; Implementation 3.5(4)]

Category: Required

Analysis: Decidable, Single Translation Unit

Applies to: C90, C99

Amplification

The following operations are covered by this rule:
  1. Assignment as defined in the Glossary;
  2. The conversion of the constant expression in a switch statement’s case label to the promoted type of the controlling expression.

Rationale

The C language allows the programmer considerable freedom and will permit assignments between different arithmetic types to be performed automatically. However, the use of these implicit conversions can lead to unintended results, with the potential for loss of value, sign or precision. Further details of concerns with the C type system can be found in Appendix C.

The use of stronger typing, as enforced by the MISRA essential type model, reduces the likelihood of these problems occurring.

Exception

  1. A non-negative integer constant expression of essentially signed type may be assigned to an object of essentially unsigned type if its value can be represented in that type.
  2. The initializer { 0 } may be used to initialize an aggregate or union type.

Example

enum enuma { A1, A2, A3   } ena;
enum enumb { B1, B2, B3   } enb;
enum       { K1=1, K2=128 };

The following are compliant:

uint8_t u8a = 0;             /* By exception                       */
bool_t flag = ( bool_t ) 0;
bool_t set  = true;          /* true is essentially Boolean        */
bool_t get  = ( u8b > u8c );

ena  = A1;
s8a  = K1;      /* Constant value fits                              */
u8a  = 2;       /* By exception                                     */
u8a  = 2 * 24;  /* By exception                                     */
cha += 1;       /* cha = cha + 1 assigns character to character     */

pu8a = pu8b;             /* Same essential type                     */
u8a  = u8b + u8c + u8d;  /* Same essential type                     */
u8a  = ( uint8_t ) s8a;  /* Cast gives same essential type          */

u32a = u16a;                /* Assignment to a wider essential type */
u32a = 2U + 125U;           /* Assignment to a wider essential type */
use_uint16 ( u8a );         /* Assignment to a wider essential type */
use_uint16 ( u8a + u16b );  /* Assignment to same essential type    */
The following are non-compliant as they have different essential type categories:
uint8_t u8a = 1.0f;  /* unsigned and floating                         */
bool_t bla  = 0;     /* boolean and signed                            */
cha  = 7;            /* character and signed                          */
u8a  = 'a';          /* unsigned and character                        */
u8b  = 1 - 2;        /* unsigned and signed                           */
u8c += 'a';          /* u8c = u8c + 'a' assigns character to unsigned */
use_uint32 ( s32a ); /* signed and unsigned                           */

The following are non-compliant as they contain assignments to a narrower essential type:

s8a  = K2;                /* Constant value does not fit */
u16a = u32a;              /* uint32_t to uint16_t        */

use_uint16 ( u32a );      /* uint32_t to uint16_t        */

uint8_t foo1 ( uint16_t x )
{
    return x;             /* uint16_t to uint8_t         */
}