Main Content

MISRA C++:2023 Rule 7.0.3

The numerical value of a character shall not be used

Since R2024b

Description

Rule Definition

The numerical value of a character shall not be used.

Rationale

When you assign an integer value to a char in C++, how that value is interpreted depends on implementation settings such as the system character encoding or locale settings. To reliably check character attributes, such as whether a character is lowercase or alphanumeric, use functions from the Standard Template Library (STL) rather than perform arithmetic on character values directly. To work with the numeric representation of characters, use the conversion functions provided by std::char_traits<> rather than manual conversions.

Polyspace Implementation

The rule checker reports a violation when the code uses the numerical value of a character, including implicit and explicit conversions to or from char. The rule checker does not report a violation when:

  • A conversion function provided by std::char_traits<> performs the conversion.

  • The numerical value of a character is used in an unevaluated context.

Troubleshooting

If you expect a rule violation but Polyspace® does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <iostream>
#include <fstream>
#include <vector>

int main() {
    std::ifstream file("example.txt");
    if (!file.is_open()) {
        std::cerr << "Error opening file." << std::endl;
        return 1;
    }

    std::vector<char> contents;
    char ch;
    while (file.get(ch)) {
        if (ch >= 'a' && ch <= 'z') {                  //Noncompliant 
            ch -= ('a' - 'A');                         //Noncompliant 
        }
        contents.push_back(ch);
    }

    file.close();

    std::ofstream outFile("example.txt");
    if (!outFile.is_open()) {
        std::cerr << "Error opening file for writing." << std::endl;
        return 1;
    }

    for (char c : contents) {
        outFile.put(c);
    }

    outFile.close();

    return 0;
}

In this example, the code reads characters from a text file and converts them from lowercase to uppercase. The code uses ASCII arithmetic to perform the conversion. This code assumes the values a to z have consecutive ASCII values 97 to 122, and A to Z have consecutive ASCII values 65 to 90.

While this code works on systems using the standard ASCII encoding, a system that uses a different encoding, such as EBCDIC, does not convert the letters the same way. Additionally, if the file contains locale-specific characters outside the standard ASCII range, the simple arithmetic conversion does not apply to those characters and it modifies them incorrectly.

Using a STL function such as std::toupper() is compliant in this scenario.

while (file.get(ch)) {
    ch = std::toupper(static_cast<unsigned char>(ch));    //Compliant
    contents.push_back(ch);
}

Check Information

Group: Standard Conversions
Category: Required

Version History

Introduced in R2024b