メインコンテンツ

MISRA C:2023 Dir 4.8

If a pointer to a structure or union is never dereferenced within a translation unit, then the implementation of the object should be hidden

R2024a 以降

説明

ルール定義

If a pointer to a structure or union is never dereferenced within a translation unit, then the implementation of the object should be hidden 1 .

根拠

構造体または共用体へのポインターがファイル内でデリファレンスされない場合、その構造体または共用体の実装の詳細をそのファイルの翻訳単位内で使用できるようにする必要はありません。構造体メンバーなどの実装の詳細を隠蔽し、意図されていない変更からそれらを保護することができます。

ポインターを介して参照できるがその内容にはアクセスできない不透明な型を定義します。

Polyspace 実装

ファイル内か、ファイルにインクルードされているヘッダー ファイル内で構造体または共用体が定義されていて、そのファイル内でこの構造体または共用体へのポインターが宣言されているが、そのポインターがデリファレンスされることがない場合、チェッカーはコーディング ルール違反にフラグを設定します。構造体または共用体の定義は、このファイルに対して可視であってはなりません。

構造体定義に関するこのルールの違反が表示された場合、同じファイル内か、そのファイルにインクルードされているヘッダー ファイル内でその構造体へのポインターを定義したかどうかを特定します。次に、ファイル内のどこかでポインターをデリファレンスしているかどうかをチェックします。ポインターをデリファレンスしていない場合、構造体定義はこのファイルから隠し、ヘッダー ファイルに含めなければなりません。

構造体のサイズは実行時に変わる可能性があります。翻訳単位内で sizeof() 演算子を使用して構造体のサイズが計算される場合、Polyspace® は、その翻訳単位内に構造体の実装が必要であると仮定します。この構造体の実装が翻訳単位内に存在する場合、Polyspace は違反を報告しません。

トラブルシューティング

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

すべて展開する

file.h:構造体実装が含まれています。


#ifndef TYPE_GUARD
#define TYPE_GUARD

typedef struct  {  //Noncompliant
  int a; 
} myStruct; 

#endif

file.c:file.h をインクルードしますが、構造体をデリファレンスしません。


#include "file.h"

myStruct* getObj(void);
void useObj(myStruct*);

void func() {
  myStruct *sPtr = getObj();
  useObj(sPtr);
}

この例では、myStruct 型へのポインターがデリファレンスされません。このポインターは単純に関数 getObj から取得され、関数 useObj に渡されます。

myStruct の実装は、file.cfile.h から構成された翻訳単位内で可視化されています。

修正 — 不透明な型を定義

1 つの修正方法として、ヘッダー ファイル file.h 内で不透明なデータ型を定義します。不透明なデータ型 ptrMyStruct は、構造体の内容を明らかにすることなく myStruct 構造体を指します。構造体 myStruct 自体は別の翻訳単位内で定義することができます。この場合、これはファイル file2.c で構成されます。構造体の定義を不透明な型の定義にリンクするために、共通のヘッダー ファイル file.hfile.c および file2.c の両方にインクルードしなければなりません。

file.h:構造体実装が含まれていません。


#ifndef TYPE_GUARD
#define TYPE_GUARD

typedef struct myStruct *ptrMyStruct; 

ptrMyStruct getObj(void);
void useObj(ptrMyStruct);

#endif

file.c:file.h をインクルードしますが、構造体をデリファレンスしません。


#include "file.h"

void func() {
  ptrMyStruct sPtr = getObj();
  useObj(sPtr);
}

file2.c:file.h をインクルードし、構造体をデリファレンスします。


#include "file.h"

struct myStruct {                                               
  int a;                                                    
};

void useObj(ptrMyStruct ptr) {
    (ptr->a)++;
}

チェック情報

グループ: Code design
カテゴリ: 推奨
AGC カテゴリ: 推奨

バージョン履歴

R2024a で導入


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.