Предупреждение C26454: Арифметическое переполнение: операция '-' приводит к отрицательному результату без знака во время компиляции (io.5) - PullRequest
0 голосов
/ 02 июля 2018

Анализ кода:

ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_HISTORY_TYPE,
  &CAssignHistoryDlg::OnTcnSelchangeTabHistoryType)

Предупреждение C26454:

Арифметическое переполнение: операция '-' дает отрицательный результат без знака во время компиляции (io.5).

Определение TCN_SELCHANGE:

#define TCN_FIRST (0U-550U)
#define TCN_SELCHANGE           (TCN_FIRST - 1)

Я не вижу, что еще я могу сделать!

Ответы [ 2 ]

0 голосов
/ 02 июля 2018
//windows header file:
#define TCN_FIRST (0U-550U)
#define TCN_SELCHANGE           (TCN_FIRST - 1)

//user file:
...
unsigned int i = TCN_SELCHANGE;

Вышеупомянутый код действителен в C ++, он должен компилироваться без предупреждения. Нет переполнения, это просто должно быть -550U Было бы более понятно, если бы они написали это как #define TCN_FIRST 0xFFFFFDDA или 0xFFFFFFFFU-549U

Анализ кода, похоже, использует другой метод и видит переполнение.

Возможное решение:

Отключить предупреждение в коде:

#pragma warning( push )
#pragma warning( disable : 26454 )

BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
    ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTabHistoryType)
END_MESSAGE_MAP()

#pragma warning( pop )

Или отключите предупреждение в правиле анализа кода
Использовать редактор набора правил анализа кода

enter image description here

0 голосов
/ 02 июля 2018

Вы пытаетесь вычесть большее беззнаковое значение из меньшего беззнакового значения, и это приводит к тому, что результат переносится за ноль. В вашем случае я предполагаю, что TCN_FIRST определен как 0, поэтому установка TCN_SELCHANGE на единицу решит проблему.

Вы также должны использовать constexpr или const вместо определений в любом случае.

По данным MSDN:

Арифметические проверки переполнения в C ++ Core Check

C26451 RESULT_OF_ARITHMETIC_OPERATION_CAST_TO_LARGER_SIZE : операция [operator] переносится за 0 и создает большое число без знака во время компиляции. Это предупреждение указывает, что операция вычитания дает отрицательный результат, который был оценен в неподписанном контексте. Это приводит к тому, что результат переносится за 0 и выдает действительно большое число без знака, что может привести к непреднамеренному переполнению.

1 // Example source:
2 unsigned int negativeunsigned() {
3    const unsigned int x = 1u - 2u; // C26454 reported here
4    return x;
5 }

1 // Corrected source:
2 unsigned int negativeunsigned() {
3     const unsigned int x = 4294967295; // OK
4     return x;
5 }

В исправленном источнике положительное значение было присвоено неподписанному результату.

...