ПроблемаНеправильное использование расширенного символьного значения происходит при преобразовании подписанного или простого символа 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();
}
}