MISRA.IF.WRAPAROUNDWrap-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. ExampleFor 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. RationaleUnsigned 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. ExampleOn 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 } } |