メインコンテンツ

MISRA C++:2023 Rule 9.6.4

A function declared with the [[noreturn]] attribute shall not return

R2024b 以降

説明

ルール定義

A function declared with the [[noreturn]] attribute shall not return. 1

根拠

コンパイラは、[[noreturn]] 属性を使用して宣言された関数は実行フローを戻さないと見なします。つまり、[[noreturn]] 関数 f()main() から呼び出された場合、コンパイラは、実行のフローが main() に戻されないことを想定します。このような関数が最終的に実行フローを戻した場合は、それが未定義の動作につながり、悪用されてデータ整合性違反を引き起こす可能性があります。

関数に return ステートメントが含まれていない場合は、関数の最後の右中かっこが暗黙的な return を意味します。関数内の return ステートメントを除外しても、実行の流れは戻されます。[[noreturn]] 関数は、以下の方法によって、実行の流れを呼び出し元の関数に戻さないようにできます。

  • 無限ループへの進入

  • 例外の発生

  • 別の [[noreturn]] 関数の呼び出し

Polyspace 実装

[[noreturn]] として指定された関数が制御フローを呼び出し元に戻す場合は、Polyspace® が関数 [[noreturn]] にフラグを設定します。

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

2 つの関数 [[noreturn]] を含む次のコードについて考えます。

#include <iostream>

[[noreturn]] void noncompliant(int i)
{
	if (i > 0)
	throw "Received positive input";
	else if (i < 0)
	std::exit(0);
} //Noncompliant
[[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
  • 関数 noncompliant() では、実行フローがコードの if-else-if ブロックをスキップし、i == 0 であれば、暗黙的に呼び出し元に戻ります。[[noreturn]] 関数はコード パス内の実行の流れを戻すため、この関数はこのルールに準拠していません。

  • 関数 compliant() では:

    • i > 0 の場合に、関数が例外を発生させます。

    • i < 0 の場合に、関数が関数 [[noreturn]] std::exit() を呼び出します。

    • i==0 の場合に、関数が無限ループに入ります。

    [[noreturn]] 関数はどのコード パスでも実行フローを戻さないため、このルールに準拠しています。

チェック情報

グループ: Statements
カテゴリ: Required

バージョン履歴

R2024b で導入


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.