メインコンテンツ

CERT C: Rec.DCL19-C

変数と関数のスコープは最小化する

説明

ルール定義

変数と関数のスコープは最小化します。1

Polyspace 実装

ルール チェッカーは以下の問題をチェックします。

  • static 指定子なしで宣言され、1 つのファイル内でのみ参照される関数またはオブジェクト

  • 必要なスコープを超えて定義されたオブジェクト

すべて展開する

問題

ルール チェッカーは以下にフラグを設定します。

  • static 指定子なしでファイル スコープで定義されているが、1 つのファイル内でしか使用されないオブジェクト。

  • static 指定子なしで定義されているが、1 つのファイル内でしか呼び出されない関数。

1 つのファイル内のみでオブジェクトまたは関数を使用する場合は、それを static として宣言します。

static 指定子なしでファイル スコープで定義されているが、1 つのファイル内でしか使用されないオブジェクト。

static 指定子なしで定義されているが、1 つのファイル内でしか呼び出されない関数。

既定の Polyspace® as You Code 解析では、チェッカーはこの問題にフラグを設定しませんPolyspace as You Code 解析で非アクティブにされるチェッカー (Polyspace Access)を参照してください

リスク

このルールに準拠することで、識別子と別の翻訳単位やライブラリ内の同一識別子との間における混乱が回避されます。内部リンクをもたせる、あるいはリンクをなくしてオブジェクトの可視性を制限または低減すると、オブジェクトに誤ってアクセスする可能性が低くなります。

例 - 1 つのファイル内で使用される外部リンクを含む変数

ヘッダー ファイル:

/* file.h */
extern int var;

1 つ目のソース ファイル:

/* file1.c */
#include "file.h"

int var;    /* Compliant */
int var2;   /* Non compliant */

void reset(void);

void reset(void) {

    static int var3=0; /* Compliant */
    var = 0;
    var2 = 0;
}

2 つ目のソース ファイル:

/* file2.c */
#include "file.h"

void increment(int var2);

void increment(int var2) {
    var++;
    var2++;
}

この例では以下のようになります。

  • var は外部リンクを含めて宣言されていて、複数のファイル内で使用されるため、var の宣言は準拠しています。

  • var2 は外部リンクを含めて宣言されているが、1 つのファイル内でしか使用されないため、var2 の宣言は準拠していません。

    両方のファイル内で var2 が定義されているように見えるかもしれません。しかし、2 つ目のファイルの var2 はリンクのないパラメーターであり、1 つ目のファイルの var2 と同じものではありません。

  • var3 は内部リンクを含めて (static 指定子を使用して) 宣言されていて、1 つのファイル内でしか使用されないため、var3 の宣言は準拠しています。

例 - 1 つのファイル内で使用される外部リンクを含む関数

ヘッダー ファイル:

/* file.h */
extern int var;
extern void increment1 (void);

1 つ目のソース ファイル:

/* file1.c */
#include "file.h"

int var;

void increment2(void);
static void increment3(void);
void func(void);

void increment2(void) { /* Non compliant */
    var+=2;
}

static void increment3(void) { /* Compliant */
    var+=3;
}

void func(void) {
    increment1();
    increment2();
    increment3();
}

2 つ目のソース ファイル:

/* file2.c */
#include "file.h"

void increment1(void) { /* Compliant */
    var++;
}

この例では以下のようになります。

  • increment1 は外部リンクを含めて定義されていて、別のファイル内で呼び出されるため、increment1 の定義は準拠しています。

  • increment2 は外部リンクを含めて定義されているが、同じファイル内以外の場所では呼び出されないため、increment2 の宣言は準拠していません。

  • increment3 は内部リンクを含めて (static 指定子を使用して) 定義されていて、同じファイル内以外の場所では呼び出されないため、increment3 の宣言は準拠しています。

問題

この問題は、オブジェクトの識別子が単一の関数にのみ現れるが、そのオブジェクトがブロック スコープを超えて定義されている場合に発生します。

ルール チェッカーは、1 つの関数内でのみアクセスされるが、ファイル スコープで宣言されている static オブジェクトにフラグを設定します。

リスク

ブロック スコープでオブジェクトを定義している場合、ブロックの外でオブジェクトに誤ってアクセスする可能性が低くなります。

例 - ファイル スコープで宣言されているものの 1 つの関数で使用されるオブジェクト
static int ctr;   /* Non compliant */

int checkStatus(void);
void incrementCount(void);

void incrementCount(void) {
    ctr=0;
    while(1) {
        if(checkStatus())
            ctr++;
    }
}

この例では、ctr の宣言が準拠していません。これがファイル スコープで宣言されているものの、関数 incrementCount でしか使用されないためです。ctrincrementCount の本体で MISRA C™ に準拠するように宣言します。

チェック情報

グループ: Rec.02.宣言と初期化 (DCL)

バージョン履歴

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.