exponenta event banner

ISO/IEC TS 17961 [signconv]

Преобразование символов со знаком в более широкие целочисленные типы перед проверкой EOF

Описание

Определение правила

Преобразование символов со знаком в более широкие целочисленные типы перед проверкой EOF. [1 ]

Внедрение Polyspace

Эта проверка проверяет, не используется ли значение символа со знаком.

Примеры

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

Проблема

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

Риск

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

Использовать в качестве индекса массива: С помощью аналогичных рассуждений нельзя использовать простую форму со знаком extended char переменные как индекс массива. Если бит знака сохранен, преобразование из char кому int может привести к отрицательным целым числам. Для индекса массива необходимо использовать положительные целочисленные значения.

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

Зафиксировать

Перед преобразованием в более широкий целочисленный тип данных приведите знак или простой char значение явно для unsigned char.

Пример - Расширенное знаковое значение по сравнению с 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 = *buf++;    
    }
    return c;
}

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

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

Коррекция - Приведение к unsigned char Перед преобразованием

Одной из возможных корректировок является отливка простой char значение для unsigned char перед преобразованием в более широкий int тип.

#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();
    }
}

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

Разрешимость: неразрешимая
Представлен в R2019a

[1] Выдержки из стандарта «ISO/IEC TS 17961 Technical Specification - 2013-11-15» воспроизводятся с согласия AFNOR. Нормативную ценность имеет только оригинальный и полный текст стандарта, опубликованный изданиями AFNOR - доступный через веб-сайт www.boutique.afnor.org.