AUTOSAR C++ 14 правил A21-8-1

Аргументы к обрабатывающим символ функциям должны быть представимыми как char без знака.

Описание

Управляйте определением

Аргументы к обрабатывающим символ функциям должны быть представимыми как char без знака.

Объяснение

Сравнение с EOF: Предположим, ваш компилятор реализует плоскость тип char, как подписано. В этой реализации символ с десятичной формой 255 (–1 в дополнительной форме two) хранится как значение со знаком. Когда вы преобразовываете переменную char в более широкий тип данных int, например, знаковый бит сохраняется (расширение знака). Это расширение знака приводит к символу с десятичной формой 255 преобразовываемый в целое число –1, который нельзя отличить от EOF.

Использование в качестве индекса массива: подобным обоснованием вы не можете использовать расширенные знаком простые переменные char в качестве индекса массива. Если знаковый бит сохраняется, преобразование от char до int может привести к отрицательным целым числам. Необходимо использовать положительные целочисленные значения для индекса массива.

Аргумент к обрабатывающей символ функции: подобным обоснованием вы не можете использовать расширенные знаком простые переменные char в качестве аргументов к обрабатывающим символ функциям, объявленным в ctype.h, например, isalpha() или isdigit(). Согласно стандарту C11 (Раздел 7.4), если вы предоставляете целочисленный аргумент, который не может быть представлен как unsigned char или EOF, получившееся поведение не определено.

Реализация Polyspace

Проверка повышает флаг когда:

  • Вы используете недействительные аргументы с целочисленной функцией от стандартной библиотеки. Эта проверка берет:

    • Преобразование символов

      toupper, tolower

    • Символьные проверки

      isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit

    • Целочисленное деление

      div, ldiv

    • Абсолютные значения

      abs, labs

  • Вы преобразовываете со знаком или плоскость тип данных char к более широкому целочисленному типу данных с расширением знака. Вы затем используете получившееся расширенное знаком значение в качестве индекса массива для сравнения с EOF или в качестве аргумента к обрабатывающей символ функции.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

развернуть все

#include <limits.h>
#include <stdlib.h>

int absoluteValue(void) {

    int neg = INT_MIN;
    return abs(neg);
}

Входным значением к abs является INT_MIN. Абсолютным значением INT_MIN является INT_MAX+1. Этот номер не может быть представлен типом int.

Исправление — изменяет входной параметр

Одно возможное исправление должно измениться, входное значение, чтобы соответствовать возвратило тип данных. В этом примере измените входное значение на INT_MIN+1.

#include <limits.h>
#include <stdlib.h>

int absoluteValue(void) {

    int neg = INT_MIN+1;
    return abs(neg);
}
#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

extern char parsed_token_buffer[20];

static int parser(char *buf)
{
    int c = EOF;
    if (buf && *buf) {
        c = *buf++;    
    }
    return c;
}

void func()
{
    if (parser(parsed_token_buffer) == EOF) { 
        /* Handle error */
        fatal_error();
    }
}

В этом примере функциональный parser может пересечь вход buf строки. Если символ в строке имеет значение-1, это может представлять или EOF или значение допустимого символа '\377' (соответствующий unsigned char эквивалентные 255). Когда преобразовано в переменную int c, его значение становится целочисленным значением-1, который всегда является EOF. Более позднее сравнение с EOF не обнаружит, если значением, возвращенным от parser, будет на самом деле EOF.

Исправление — бросок к unsigned char перед преобразованием

Одно возможное исправление должно бросить плоскость значение char к unsigned char перед преобразованием в более широкий тип int. Только затем можете вы тестировать, если возвращаемым значением parser является действительно EOF.

#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

extern char parsed_token_buffer[20];

static int parser(char *buf)
{
    int c = EOF;
    if (buf && *buf) {
        c = (unsigned char)*buf++;    
    }
    return c;
}

void func()
{
    if (parser(parsed_token_buffer) == EOF) { 
        /* Handle error */
        fatal_error();
    }
}

Проверяйте информацию

Группа: библиотека Strings

Введенный в R2019a