メインコンテンツ

CERT C++: ERR59-CPP

Do not throw an exception across execution boundaries

R2022b 以降

説明

ルール定義

Do not throw an exception across execution boundaries.1

Polyspace 実装

ルール チェッカーは、"ライブラリ インターフェイスによって発生する例外" をチェックします。

すべて展開する

問題

この問題は、以下の条件が両方当てはまる場合に発生します。

  • 関数が実行境界をまたがるように指定されている。

  • 関数で例外が発生する。

Polyspace® は、ライブラリ インターフェイス関数が実行境界をまたがると仮定します。ライブラリ インターフェイス関数内の new 演算子によって std::bad_alloc 例外が発生する場合、違反は報告されません。

このチェッカーを正しく使用するには、コード内のライブラリ インターフェイス関数を指定します。関数 foo()visibility 属性を設定して、この関数をライブラリ インターフェイス関数として宣言します。次に例を示します。

  • GNU および Clang コンパイラ: void __attribute__((visibility("default"))) foo(){/*...*/}

  • Visual Studio: void __declspec(dllexport) foo(){/**.../}

関数を可視として明示的に指定しない場合、Polyspace は、その関数がライブラリ インターフェイスの一部ではないと仮定します。

リスク

Exception Handling には、例外を発生させる関数と、発生した例外を処理する関数との間に相互運用性が必要です。ライブラリ関数が、互換性のないインターフェイスを使用して Exception Handling を実装していることもあります。次に例を示します。

// lib.h
void foo() noexcept(false);
//lib.cpp
void foo() noexcept(false){
  //...
  throw 42;
}
//App.cpp
#include"lib.h"
int main(){
  try{
    foo();
  }catch(int& e){
    //handle exception
  }
}
たとえば、GCC 4.9 コンパイラを使用してコンパイルされたライブラリ インターフェイス lib.cpp を使用しているとします。そこで、Microsoft® Visual Studio® を使用してアプリケーション App.cpp をコンパイルします。コードのこれら 2 つの部分では、互換性のない例外処理インターフェイスが使用されています。ライブラリ インターフェイス関数によって例外が発生した場合、その例外は処理されず、アプリケーションが予期せず終了します。

修正方法

ライブラリ インターフェイスでの例外の発生を回避します。例外を発生させる代わりに、予期しない状況を処理するために別のエラー コードを返します。

例 — 可視の関数によって発生する例外

#include<exception>

void __attribute__((visibility("default"))) foo(int rd) noexcept(false) { //Noncompliant
    if (rd==-1)
        throw std::exception();
}

この例では、関数 foo()visibility 属性が default に設定されています。foo() は、別の Exception Handling メカニズムを使用しているモジュール内で使用されている場合もあるため、foo() によって発生した例外が処理されないままになる可能性があります。可視の関数による例外の発生を回避します。

修正 — 別の方法を使用してエラーを処理する

エラーを処理するための別の方法を使用します。たとえば、コード内で論理エラーが発生したら、エラー フラグを設定して、エラー コードを返します。

#include<exception>
int FLAG;

int __attribute__((visibility("default"))) foo(bool rd) noexcept(true) { 
    if (rd==-1){
		FLAG = 52;
		return -1;//Compliant
	}
}

チェック情報

グループ: 08.例外とエラーの取り扱い (ERR)

バージョン履歴

R2022b で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.