Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V1070. Signed value is converted to an unsigned one with subsequent expansion to a larger type in ternary operator.

17 Май 2021

Анализатор обнаружил ситуацию, при которой результат тернарного оператора, операнды которого имеют целые типы, различные по знаку, сохраняется в целый тип большего размера любой знаковости. При таком преобразовании отрицательное значение станет положительным.

Рассмотрим синтетический пример:

long long foo(signed int a, unsigned int b, bool c)
{
  return c ? a : b;
}

Согласно правилам преобразования в C++, если второй и третий операнды тернарного оператора содержат разные типы, и размер беззнакового операнда не меньше размера знакового, то компилятор преобразует их к беззнаковому типу.

Таким образом, знаковая переменная с отрицательным значением (например, -1) будет приведена к беззнаковому типу. В случае 32-битного типа 'int' итоговое значение будет '0xFFFFFFFF'. Затем этот результат будет преобразован в целый тип большего размера (64-битный тип 'long long'), однако исходная знаковость уже была потеряна, и финальный результат так и останется в виде положительного числа.

Проблема сохраняется также для случая, когда результат тернарного оператора преобразуется в беззнаковый тип большей размерности:

unsigned long long f(signed int i, unsigned int ui, bool b)
{
  return b ? i : ui;
}

Если переменная 'i' имеет отрицательное значение (например, -1), то результатом тернарного оператора будет значение '0xFFFFFFFF'. Затем оно будет преобразовано в беззнаковый тип большего размера, и его значение станет '0x00000000FFFFFFFF'. Скорее всего программист ожидал, что результатом будет значение '0xFFFFFFFFFFFFFFFF'.

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки целочисленного переполнения и некорректного совместного использования знаковых и беззнаковых чисел.

Данная диагностика классифицируется как: