This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 7.0.3 - The numerical value of a character shall not be used
Category: Required
Analysis: Decidable,Single Translation Unit
Amplification
There shall be no implicit or explicit conversion to or from an expression with character category.
This rule does not apply to unevaluated operands, or to the operands of an equality operator when both have the same character
type.
Rationale
Types in the character category are used to represent characters, not integers. The meaning of the integer value of a character type
depends on behaviour outside of the program and the C++ language, such as the encoding that is being used.
When other operations on characters are necessary, such as determining if a character is lower case, C++ Standard Library functions provide
solutions that are safer than the arithmetic manipulation of character values.
Where the underlying numeric representation of character data is required, such as when generating a hash, appropriate conversion functions are
provided by std::char_traits<>.
Example
char a = 'a'; // Rule does not apply - no conversion
char b = '\r'; // Rule does not apply - no conversion
char c = 10; // Non-compliant - implicit conversion from int to char
int8_t d = 'a'; // Non-compliant
uint8_t e = '\r'; // Non-compliant
signed char f = 11; // Rule does not apply - type has integral category
using CT = std::char_traits< char >;
char g = L'Æ'; // Non-compliant - conversion between character types
char h = a - '0'; // Non-compliant - promotion to int, conversion to char
if ( g && h ) // Non-compliant - two conversions to bool
if ( a != 'q' ) // Rule does not apply - comparing the same types
if ( CT::eq( a, 'q' ) ) // Rule does not apply - no conversion
std::optional< char > o;
if ( o == 'r' ) // Rule does not apply - no conversion
decltype( 's' + 't' ) w; // Rule does not apply - unevaluated operand
auto i = static_cast< CT::int_type >( 'a' ); // Non-compliant - explicitly
// converted to CT::int_type
auto j = CT::to_int_type( 'a' ); // Rule does not apply
// - no conversion
if ( ( a >= '0' ) && ( a <= '9' ) ) // Non-compliant - promotion to int
if ( !CT::lt( a, '0' ) && !CT::lt( '9', a ) ) // Compliant version of the above
if ( 0 == std::isdigit( a ) ) // Non-compliant - conversion to int
if ( std::isdigit( a, std::locale {} ) ) // Compliant version of the above
void f1 ( std::istream & is )
{
auto i = is.get();
if ( CT::not_eof( i ) )
{
char c1 = i; // Non-compliant - int to char
char c2 = CT::to_char_type( i ); // Compliant version of the above
}
}
Copyright The MISRA Consortium Limited © 2023