cppcheck — натыкаюсь на нетривиальный сценарий bool в Stack Overflow

Когда Cppcheck запускает этот код,[1] это жалуется на ошибка:

void bool_express(bool aPre, bool aX, bool aPost)
{
bool x;
const bool pre = aPre;
if (pre) {
x = aX;
}
const bool post = aPost;

// error checking passage of the original code:
if ( !pre || !x || !post ) {
if ( !pre ) {
trace("pre failed");
} else if ( !x ) {       // <-- HERE Cppcheck complains
trace("x failed");
} else {
trace("post failed");
}
} else {
// success passage of the original code:
trace("ok");
}
}

Это сообщение, которое заставляет меня нервничать:

Id: uninitvar
Summary: Uninitialized variable: x
Message: Uninitialized variable: x

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

Вы когда-нибудь сталкивались с подобными ситуациями? Как с этим бороться?


[1] Этот код сводится к его костям, исходный код устанавливает предварительное условие (pre) что-то делает (x), то форсирует постусловие (post), после этого проверяются некоторые условия ошибки. Я преобразовал результаты выполнения функций, которые вызываются и затем сохраняются в pre, x, а также post в 3 аргумента моего теста.

1

Решение

Это ложно положительный в Cppcheck. я решена это путем добавления встроенного подавления:[1]

    if ( !pre ) {
trace("pre failed");
// cppcheck-suppress uninitvar
} else if ( !x ) {
trace("x failed");
} else {
trace("post failed");
}

и я также довел это до сведения разработчиков Cppcheck:

# 7663 (Ложно-положительный: неинициализированная переменная в недоступном коде)


[1] Я решил не инициализировать переменную. Это не из-за соображений производительности, но чтобы быть в курсе об ошибке, которая будет исправлена ​​в следующем выпуске, когда Cppcheck скажет

Id: unmatchedSuppression
Summary: Unmatched suppression: uninitvar
Message: Unmatched suppression: uninitvar
1

Другие решения

Статический анализ, кажется, жалуется, потому что если pre ложь, то x никогда не устанавливается.

Ваш код структурирован так, что значение x никогда не доступен, если pre является false — я бы сказал, что в этом случае статический анализатор не дает полезного вывода.

Перечислим различные случаи, которые у нас есть (поэтому мы можем быть достаточно уверены, что это cppcheck, а не мы!):

  1. Первое утверждение, в котором x доступ находится в линии if ( !pre || !x || !post ) — из-за оценка короткого замыкания: if( A || B || C ) не оценивает B или же C если A правда; следовательно, мы никогда не пытаемся читать неинициализированный x (поскольку x только неинициализирован, если pre ложь, в этом случае мы перестали вычислять выражение!)

  2. Второе использование в

    if ( !pre ) {
    trace("pre failed");
    } else if ( !x ) { // <-- HERE Cppcheck complains

    Опять же, мы можем попасть на оскорбительную линию, только если pre было правдой (в этом случае x правильно инициализирован).

Из этого можно сделать вывод, что либо:

  1. Фактический код по ошибке пытается прочитать x в каком-то состоянии даже есть pre ложно, и вы упустили его при построении примера (иногда логический ход программы может быть немного тупым)

  2. Статический анализатор ленив и замечает линию else if( !x ) и не может определить, достижима ли эта строка с неинициализированным значением.

Исходя из предоставленного вами кода, вы не должны беспокоиться: инструмент статического анализа технически правильно x может быть неинициализирован, но в этих случаях он не используется (и, следовательно, вероятно, не должен вас предупреждать).

Я бы порекомендовал назначить x значение по умолчанию, если вы не уверены, или если фактическая логика очень тупая.

1

Если твой pre состояние false чем х будет неинициализирован. На линии if ( !x ) CppCheck предупреждает об использовании неопределенного значения. Чтобы исправить это инициализировать x переменная.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector