メインコンテンツ

MISRA C:2012 Rule 8.7

Functions and objects should not be defined with external linkage if they are referenced in only one translation unit

説明

このチェッカーは、既定の Polyspace® as You Code™ 解析では非アクティブにされます。Checkers Deactivated in Polyspace as You Code Analysis (Polyspace as You Code)を参照してください。

ルール定義

Functions and objects should not be defined with external linkage if they are referenced in only one translation unit 1 .

根拠

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

Polyspace 実装

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

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

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

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

custom と一緒に [入力] (-variables-written-in-loop)[パラメーター] (-variables-written-before-loop) などのオプションを使用して、初期化する変数のセットを明示的に指定した場合は、チェッカーがそれらの変数にフラグを設定しません。チェッカーは、実際のアプリケーションでは、現在これらの変数を使用しているファイルに加えて、main が含まれるファイルでもこれらの変数を初期化する必要があると見なします。そのため、変数は複数の翻訳単位内で使用されます。

トラブルシューティング

ルール違反を想定していてもその違反が表示されない場合、コーディング規約違反が想定どおりに表示されない理由の診断を参照します。

すべて展開する

ヘッダー ファイル:


/* file.h */
extern int var;

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


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

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

void reset(void);

void reset(void) {
    var = 0;
    var2 = 0;
    var3 = 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 の宣言は準拠しています。

ヘッダー ファイル:


/* 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 の宣言は準拠しています。

この例では、関数 get_pi()extern として宣言されていますが、この関数は単一の翻訳単位で使用されています。Polyspace は違反を報告します。

extern double get_pi(void) // Noncompliant
{
    //....
    return 3.1416;
}

void foo(){
    
 get_pi(); 
}
修正 — get_pi()static として宣言する

この違反を修正するには、関数 get_pi()static 関数として宣言します。

static double get_pi(void) // Compliant
{
    //....
    return 3.1416;
}

void foo(){
    
 get_pi(); 
}

チェック情報

グループ: 宣言と定義
カテゴリ: 推奨
AGC カテゴリ: 推奨
PQL 名: std.misra_c_2012.R8_7

バージョン履歴

R2014b で導入


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.