メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C: Rule EXP35-C

有効期間が一時的なオブジェクトを変更しない

説明

ルール定義

有効期間が一時的なオブジェクトを変更しないようにします。1

Polyspace 実装

ルール チェッカーは、"有効期間が一時的なオブジェクトにアクセスしています" をチェックします。

すべて展開する

問題

[有効期間が一時的なオブジェクトにアクセスしています] は、関数呼び出しから返された、有効期間が一時的なオブジェクトに対して読み取りまたは書き込みを試みると発生します。関数から返された、配列が含まれている構造体または共用体では、それらの配列メンバーは一時オブジェクトです。一時オブジェクトの有効期間が終了するのは、以下のとおりです。

  • C11 規格で定義されているように、その呼び出しを含む完全な式または完全な宣言子が終了したとき。

  • C90 および C99 規格で定義されているように、次のシーケンス ポイントの後。シーケンス ポイントとは、プログラムの実行において、すべての前の評価が完了し、以降の評価がまだ開始されていない時点のことです。

C++ コードでは、有効期間が一時的なオブジェクトに書き込みを行う場合のみ、[有効期間が一時的なオブジェクトにアクセスしています] によって欠陥が報告されます。

有効期間が一時的なオブジェクトがアドレスで返された場合、欠陥は報告されません。

リスク

有効期間が一時的なオブジェクトの変更は未定義の動作であり、プログラムの異常終了と移植性の問題の原因になる可能性があります。

修正方法

関数呼び出しから返されたオブジェクトをローカル変数に代入します。有効期間が一時的なオブジェクトの内容がこの変数にコピーされます。安全にこれを変更できるようになります。

例 - 関数呼び出しから返された、有効期間が一時的なオブジェクトの変更
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define SIZE6 6

struct S_Array
{
    int t;
    int a[SIZE6];
};

struct S_Array func_temp(void);

/* func_temp() returns a struct value containing
* an array with a temporary lifetime.
*/
int func(void) {
 
/*Writing to temporary lifetime object is
 undefined behavior
 */
    return ++(func_temp().a[0]);  //Noncompliant
}

void main(void) {
    (void)func();
}

この例では、func_temp() は配列メンバー a をもつ構造体を値で返します。このメンバーの有効期間は一時的です。これをインクリメントすることは未定義の動作です。

修正 — 書き込み前にローカル変数に戻り値を代入

1 つの修正方法として、func_temp() の呼び出しの戻り値をローカル変数に代入します。一時オブジェクト a の内容がこの変数にコピーされ、これを安全にインクリメントできます。

 #include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define SIZE6 6

struct S_Array
{
    int t;
    int a[SIZE6];
};

struct S_Array func_temp(void);

int func(void) {

/* Assign object returned by function call to 
 *local variable
 */
    struct S_Array s = func_temp(); 

/* Local variable can safely be
 *incremented
 */
    ++(s.a[0]);                                           
    return s.a[0];
}

void main(void) {
    (void)func();
}

チェック情報

グループ: Rule 03.式 (EXP)

バージョン履歴

R2019a で導入


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.