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.IF.WRAPAROUND

Wrap-around in #if directive.

MISRA-C Rule 12.11 (advisory): Evaluation of constant unsigned integer expressions should not lead to wrap-around.

This rule is also covered by MISRA.ELIF.WRAPAROUND and MISRA.COMP.WRAPAROUND.

Because unsigned integer expressions do not strictly overflow, but instead wrap around in a modular way, any constant unsigned integer expressions which in effect "overflow" will not be detected by the compiler. Although there may be good reasons at run-time to rely on the modular arithmetic provided by unsigned integer types, the reasons for using it at compile-time to evaluate a constant expression are less obvious. Any instance of an unsigned integer constant expression wrapping around is therefore likely to indicate a programming error.

This rule applies equally to all phases of the translation process. Constant expressions that the compiler chooses to evaluate at compile time are evaluated in such a way that the results are identical to those that would be obtained by evaluation on the target with the exception of those appearing in conditional preprocessing directives. For such directives, the usual rules of arithmetic (see section 6.4 of ISO/IEC 9899:1990 [2]) apply but the int and unsigned int types behave instead as if they were long and unsigned long respectively.

Example

For example, on a machine with a 16-bit int type and a 32-bit long type:

#define START 0x8000
#define END 0xFFFF
#define LEN 0x8000

#if ((START + LEN) > END)
   #error Buffer Overrun
             /* OK because START and LEN are unsigned long            */
#endif

#if (((END - START) - LEN) < 0)
   #error Buffer Overrun
             /* Not OK: subtraction result wraps around to 0xFFFFFFFF */
#endif

/* contrast the above START + LEN with the following */

if ((START + LEN) > END)
{
   error ("Buffer overrun");
            /* Not OK: START + LEN wraps around to 0x0000
               due to unsigned int arithmetic                         */
}

MISRA-C++ Rule 5-19-1 (advisory): Evaluation of constant unsigned integer expressions should not lead to wrap-around.

This rule is also covered by MISRA.ELIF.WRAPAROUND and MISRA.COMP.WRAPAROUND.

Rationale

Unsigned integer expressions do not strictly overflow, but instead wrap around in a modular way. Any constant unsigned integer expressions that in effect "overflow" will not be detected by the compiler. Although there may be good reasons at run-time to rely on the modular arithmetic provided by unsigned integer types, the reasons for using it at compile-time to evaluate a constant expression are less obvious. Any instance of an unsigned integer constant expression wrapping around is therefore likely to indicate a programming error.

This rule applies equally to all phases of the translation process. Constant expressions that the compiler chooses to evaluate at compile time are evaluated in such a way that the results are identical to those that would be obtained by evaluation on the target, with the exception of those appearing in conditional preprocessing directives. For such directives, the usual rules of arithmetic apply but the int and unsigned int types behave instead as if they were long and unsigned long respectively.

Example

On a machine with a 16-bit int type and a preprocessor using a 32-bit long type:

#define START 0x8000
#define END 0xFFFF
#define LEN 0x8000

#if ( ( START + LEN ) > END )
#error Buffer Overrun // OK as START and LEN are unsigned long
#endif

#if ( ( ( END — START ) — LEN ) < 0 )
   #error Buffer Overrun
   // Not OK: subtraction result wraps around to 0xFFFFFFFF
#endif

// contrast the above START + LEN with the following
void fn ( )
{
   if ( ( START + LEN ) > END )
   {
      error ( "Buffer overrun" );
      // Not OK: START + LEN wraps around to 0x0000 due to unsigned int
      // arithmetic
   }
}