exponenta event banner

CERT C++: MSC53-CPP

Не возвращать из функции, объявленной [[noreturn]]

Описание

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

Не возвращать из функции, объявленной [[noreturn]] [1 ]

Внедрение Polyspace

Эта проверка проверяет наличие [[noreturn]] функции, возвращаемые в Caller.

Примеры

развернуть все

Проблема

Этот дефект возникает при [[noreturn]] функция в конечном итоге возвращает поток выполнения функции вызывающего абонента. Компилятор ожидает, что функция, объявленная с помощью [[noreturn]] не возвращает поток выполнения. То есть, если [[noreturn]] функция f() вызывается из main(), то компилятор ожидает, что поток выполнения не будет возвращен main(). Если такая функция в конечном итоге возвращает поток выполнения, это приводит к неопределенному поведению.

Риск

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

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

Если функция не имеет return оператор, то заключительная закрывающая скобка функции подразумевает неявное return. Пропуск return оператор в функции не препятствует возврату потока выполнения. A [[noreturn]] функция может запретить возврат потока выполнения вызывающей функции посредством:

  • Ввод бесконечного цикла

  • Создание исключения

  • Вызов другого [[noreturn]] функция

Пример

Рассмотрим следующий код, содержащий функцию noncompliant(), которая объявлена как [[noreturn]].

#include <cstdlib>
[[noreturn]] void bad_f(int i)
{
	if (i > 0)
	throw "Received positive input";
	else if (i < 0)
	std::exit(0);
} //Noncompliant

Когда вход i равно нулю, поток выполнения пропускает if-else-if блок кода и возвращается вызывающему абоненту неявно. Потому что [[noreturn]] функция возвращает поток выполнения в кодовом пути, эта функция не соответствует этому правилу.

Исправление

A [[noreturn]] функция не должна возвращать поток выполнения в кодовом пути. Вы можете предотвратить возврат несколькими способами. Рассмотрим следующий код, где [[noreturn]] функция не возвращает поток выполнения в кодовом пути.

#include <cstdlib>
[[noreturn]] void compliant(int i)
{
	if (i > 0)
	throw "Received positive input";
	else if (i < 0)
	std::exit(0);
	else if(i==0)
	while(true){
		//...
	}
}//Compliant

Эта функция соответствует этому правилу, поскольку:

  • Когда i > 0, функция вызывает исключение.

  • Когда i < 0, функция вызывает [[noreturn]] функция std::exit().

  • Когда i==0, функция входит в бесконечный цикл.

Потому что [[noreturn]] функция не возвращает поток выполнения в пути вызова, она соответствует этому правилу.

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

Группа: 49. Разное (MSC)
Представлен в R2020b

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

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

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