メインコンテンツ

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

MISRA C++:2023 Rule 19.2.1

Precautions shall be taken in order to prevent the contents of a header file being included more than once

R2024b 以降

説明

ルール定義

Precautions shall be taken in order to prevent the contents of a header file being included more than once. 1

根拠

入れ子にされたヘッダー ファイルの複雑な階層が翻訳単位に含まれる場合、特定のヘッダー ファイルが 2 回以上インクルードされ、混乱の原因になる可能性があります。複数回のインクルードにより複数の定義または定義の競合が生じる場合、プログラムで未定義の動作または誤動作が発生する可能性があります。

たとえば、ヘッダー ファイルに以下が含まれるとします。

#ifdef _WIN64
   int env_var;
#elseif  
   long int env_var;
#endif
ヘッダー ファイルが 2 つのインクルード パス (マクロ _WIN64 を定義するパスと定義解除するパス) に含まれる場合、env_var の定義の競合が発生する可能性があります。

同一ファイルが複数回インクルードされることを避けるには、ヘッダー ファイルの先頭にインクルード ガードを追加します。次のいずれかの形式を使用します。

  • <start-of-file>
    // Comments allowed here
    #if !defined ( identifier )
    #define identifier
    // Contents of file
    #endif
    <end-of-file>
    
  • <start-of-file>
    // Comments allowed here
    #ifndef identifier
    #define identifier
    // Contents of file
    #endif
    <end-of-file>

Polyspace 実装

チェッカーは、ヘッダー ファイルにインクルード ガードが含まれていない場合、または正しくない形式のインクルード ガードが含まれている場合に違反を報告します。

たとえば、次のコードは #define および #include ステートメントのインクルード ガードを使用しています。このコードはルール違反ではありません。

// Contents of a header file
#ifndef FILE_H
#define FILE_H
#include "libFile.h"
#endif
提案される形式に準拠しないインクルード ガードを使用すると、Polyspace® はそれらにフラグを設定します。次に例を示します。

  • #ifndef および #define ステートメントで、誤って異なる識別子を使用する可能性があります。

    #ifndef MACRO
    #define MICRO
    //...
    #endif

  • 意図せずに、#ifndef の代わりに #ifdef を使用したり、#define ステートメントを省略したりする可能性があります。

トラブルシューティング

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

すべて展開する

file1.hfile2.hmainfile.cpp
#ifndef MACRO
#define MICRO
//...
#endif
#ifdef DO_INCLUDE
#define DO_INCLUDE
void foo();
#endif
#include"file1.h"
#include"file2.h"
int main(){
	return 0;
}

この例では、2 つのヘッダー ファイルがファイル mainfile.cpp にインクルードされています。

  • file1.h のインクルード ガードは MACRO の定義をクエリしますが、おそらく誤って、条件付きで異なる識別子 MICRO を定義しています。このインクルード ガードの形式は正しくないため、Polyspace はこのファイルにフラグを設定します。

  • file2.h のインクルード ガードは、#ifndef の代わりに #ifdef を使用しています。このインクルード ガードは正しくないため、Polyspace はこのファイルにフラグを設定します。

チェック情報

グループ: Preprocessing Directives
カテゴリ: 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.