ISO/IEC TS 17961 [signconv]

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

Описание

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

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

Примеры

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

Описание

Неправильное употребление значения расширенного символа знака происходит, когда вы преобразуете со знаком или плоскость 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 - имеет нормативное значение.