exponenta event banner

CERT C++: CON41-C

Оберните функции, которые могут внезапно неудачить в цикле

Описание

Определение правила

Оберните функции, которые могут внезапно неудачить в цикле.[1]

Реализация Polyspace

Эта проверка проверяет Функцию, которая может ложно не обернуться в цикле.

Примеры

расширить все

Проблема

Функция, которая может ложно отказать, не завернутая в цикл, возникает, когда следующие атомарные функции сравнения и обмена, которые могут ошибочно завершиться, вызываются из-за пределов цикла.

  • Атомарные функции C:

    • atomic_compare_exchange_weak()

    • atomic_compare_exchange_weak_explicit()

  • C++ атомарные функции:

    • std::atomic<T>::compare_exchange_weak(T* expected, T desired)

    • std::atomic<T>::compare_exchange_weak_explicit(T* expected, T desired, std::memory_order succ, std::memory_order fail)

    • std::atomic_compare_exchange_weak(std::atomic<T>* obj, T* expected, T desired)

    • std::atomic_compare_exchange_weak_explicit(volatile std::atomic<T>* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail)

Функции сравнивают содержимое памяти представлений объектов, на которые указывает obj и expected. Сравнение может ложно вернуть false, даже если содержимое памяти равное. Этот ложный отказ делает функции быстрее на некоторых платформах.

Риск

Атомарная функция сравнения и обмена, которая ложно отказывает, может вызвать неожиданные результаты и неожиданный поток управления.

Зафиксировать

Оберните атомарные функции сравнения и обмена, которые могут ложно отказать в цикле. Цикл проверяет условие отказа после возможного ложного отказа.

Пример - atomic_compare_exchange_weak() Не обернутый в цикл
#include <atomic>
#include <stdbool.h>
using namespace std;
static atomic<bool> flag(false);
void toggle_flag(void)
{
	bool old_flag = atomic_load(&flag);
	bool new_flag;
	if (!atomic_compare_exchange_weak(&flag, &old_flag, new_flag)){//Noncompliant
		new_flag = !old_flag;
	}

}

bool get_flag(void)
{
	return atomic_load(&flag);
}

В этом примере функция toggle_flag использует atomic_compare_exchange_weak() для сравнения flag и old_flag. Если переменные идентичны, flag переключается на new_flag. Когда atomic_compare_exchange_weak() отказывает ложно, флаг переключается без необходимости.

Коррекция - Обернуть atomic_compare_exchange_weak() в do-while Цикл

Одной из возможных коррекций является перенос вызова в atomic_compare_exchange_weak() в while цикл. Цикл проверяет условие отказа после возможного ложного отказа.

#include <atomic>
#include <stdbool.h>
using namespace std;
static atomic<bool> flag(false);


void toggle_flag(void)
{
  bool old_flag = atomic_load(&flag);
  bool new_flag;
  do {
    new_flag = !old_flag;
  } while (!atomic_compare_exchange_weak(&flag, &old_flag, new_flag));

}

bool get_flag(void)
{
    return atomic_load(&flag);
}

Проверяйте информацию

Группа: 10. Параллелизм (CON)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.