ISO/IEC TS 17961 [signconv]

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

Описание

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

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

Реализация Polyspace

Это средство проверки проверяет на Неправильное употребление значения расширенного символа знака.

Примеры

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

Проблема

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

Риск

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

Использование в качестве индекса массива: подобным обоснованием вы не можете использовать расширенную знаком плоскость 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 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.