メインコンテンツ

CERT C: Rec.DCL23-C

相互に可視の識別子は一意になることを保証する

説明

ルール定義

相互に可視の識別子は一意になることを保証します。1

Polyspace 実装

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

  • 外部識別子が区別されていない

  • 同じスコープかつ同じ名前空間の識別子が区別されていない

  • マクロ識別子が区別されていない

  • マクロと識別子の名前が区別されていない

すべて展開する

問題

この問題は、C90 では複数の外部識別子の最初の 6 文字が同じ場合に発生し、C99 では複数の外部識別子の最初の 31 文字が同じ場合に発生します。

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

リスク

外部識別子はグローバル スコープまたはストレージ クラス extern で宣言されています。

Polyspace は最初の 31 文字の間に相違点があれば 2 つの名前を別個であると見なします。最初の 31 文字を超えた範囲のみに 2 つの名前の相違点が存在する場合、両者が混同される可能性が高くなります。コードの可読性は低下します。C90 では相違点は最初の 6 文字の間に存在しなければなりません。C90 ルール チェックを使用するには、オプション [C 標準バージョン] (-c-version) で値 c90 を使用します。

例 - C90: 識別子の最初の 6 文字が一意でない
int engine_temperature_raw;
int engine_temperature_scaled;   /* Non-compliant */					
int engin2_temperature;          /* Compliant */	

この例では、識別子 engine_temperature_scaled の最初の 6 文字が、先行する識別子 engine_temperature_raw の文字と同じです。

例 - C99: 識別子の最初の 31 文字が一意でない
int engine_exhaust_gas_temperature_raw;
int engine_exhaust_gas_temperature_scaled; /* Non-compliant */					

int eng_exhaust_gas_temp_raw;
int eng_exhaust_gas_temp_scaled;           /* Compliant */						

この例では、識別子 engine_exhaust_gas_temperature_scaled の最初の 31 文字が、先行する識別子 engine_exhaust_gas_temperature_raw の文字と同じです。

例 - C90: 別々の翻訳単位における最初の 6 文字の識別子が、大文字小文字の違いのみで区別されている
/* file1.c */
int abc = 0;
/* file2.c */
int ABC = 0; /* Non-compliant */

この例では、実装において大文字と小文字を区別しない 6 つの有意文字が "外部識別子" でサポートされています。2 つの翻訳で識別子は異なっていますが、有意文字では区別されません。

問題

この問題は、複数の識別子を同じスコープかつ同じ名前空間で宣言するときに、C90 ではそれらの識別子の最初の 31 文字が同じ場合、C99 ではそれらの識別子の最初の 63 文字が同じ場合に発生します。

リスク

Polyspace は最初の 63 文字の間に相違点があれば 2 つの名前を別個であると見なします。2 つの名前が最初の 63 文字を超えた範囲のみに相違点が存在している場合、両者が混同される可能性が高くなります。コードの可読性は低下します。C90 では相違点は最初の 31 文字の間に存在しなければなりません。C90 ルール チェックを使用するには、オプション [C 標準バージョン] (-c-version) で値 c90 を使用します。

例 - C90: 識別子の最初の 31 文字が一意でない
extern int engine_exhaust_gas_temperature_raw;
static int engine_exhaust_gas_temperature_scaled;      /* Non-compliant */

extern double engine_exhaust_gas_temperature_raw;
static double engine_exhaust_gas_temperature2_scaled;  /* Compliant */

void func ( void )
{
  /* Not in the same scope */
  int engine_exhaust_gas_temperature_local;            /* Compliant */
}

この例では、識別子 engine_exhaust_gas_temperature_scaled の 31 文字が、先行する識別子 engine_exhaust_gas_temperature_raw の文字と同じです。

2 つの識別子の 31 文字が同じであっても、スコープが異なる場合、このルールは適用されません。たとえば、engine_exhaust_gas_temperature_local には engine_exhaust_gas_temperature_raw と同じ 31 文字がありますが、スコープが異なります。

例 - C99: 識別子の最初の 63 文字が一意でない
extern int engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_raw;
static int engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_scale;
    /* Non-compliant */

extern int engine_gas_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx__raw;
static int engine_gas_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx__scale;
    /* Compliant */

void func ( void )
{
/* Not in the same scope */
    int engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_local;
          /* Compliant */
}

この例では、識別子 engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_scale の 63 文字が、先行する識別子 engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_raw の文字と同じです。

問題

この問題は、C90 では最初の 31 文字が同じ複数のマクロ識別子を使用する場合に発生し、C99 では最初の 63 文字が同じ複数のマクロ識別子を使用する場合に発生します。

リスク

マクロ識別子の名前は他のマクロ識別子およびそのパラメーターと別個でなければなりません。

Polyspace は最初の 63 文字の間に相違点があれば 2 つの名前を別個であると見なします。2 つの名前が最初の 63 文字を超えた範囲のみに相違点が存在している場合、両者が混同される可能性が高くなります。コードの可読性は低下します。C90 では相違点は最初の 31 文字の間に存在しなければなりません。C90 ルール チェックを使用するには、オプション [C 標準バージョン] (-c-version) で値 c90 を使用します。

例 - C90: マクロ名の最初の 31 文字が一意でない
#define engine_exhaust_gas_temperature_raw egt_r
#define engine_exhaust_gas_temperature_scaled egt_s   /* Non-compliant */

#define engine_exhaust_gas_temp_raw egt_r
#define engine_exhaust_gas_temp_scaled egt_s          /* Compliant */

この例では、マクロ engine_exhaust_gas_temperature_scaled egt_s の最初の 31 文字が、先行するマクロ engine_exhaust_gas_temperature_scaled の文字と同じです。

例 - C99: マクロ名の最初の 63 文字が一意でない

#define engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_raw egt_r
#define engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_raw_scaled egt_s
    /* Non-compliant */

/* 63 significant case-sensitive characters in macro identifiers */
#define new_engine_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_raw egt_r
#define new_engine_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_scaled egt_s
    /* Compliant */

この例では、マクロ engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx___gaz_scaled の最初の 63 文字が、先行するマクロ engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx___raw の文字と同じです。

問題

この問題は、識別子がマクロ名と区別されていない場合に発生します。

リスク

ルールでは、処理の前にのみ存在するマクロ名は、前処理後にも存在する識別子名と異なっていなければなりません。マクロ名と識別子を区別することで、混乱を回避できます。

Polyspace は最初の 63 文字の間に相違点があれば 2 つの名前を別個であると見なします。2 つの名前が最初の 63 文字を超えた範囲のみに相違点が存在している場合、両者が混同される可能性が高くなります。コードの可読性は低下します。C90 では相違点は最初の 31 文字の間に存在しなければなりません。C90 ルール チェックを使用するには、オプション [C 標準バージョン] (-c-version) で値 c90 を使用します。

例 - マクロ名が識別子名と同じ
#define Sum_1(x, y) ( ( x ) + ( y ) )
short Sum_1;                    /* Non-compliant */

#define Sum_2(x, y) ( ( x ) + ( y ) )
short x = Sum_2 ( 1, 2 );       /* Compliant */

この例では、Sum_1 が識別子とマクロの両方の名前となっています。Sum_2 はマクロとしてのみ使用されます。

例 - C90: マクロ名の最初の 31 文字が識別子名と同じ
#define	   low_pressure_turbine_temperature_1 lp_tb_temp_1
static int low_pressure_turbine_temperature_2;	  /* Non-compliant  */	

この例では、識別子 low_pressure_turbine_temperature_2 の最初の 31 文字が、先行するマクロ low_pressure_turbine_temperature_1 の文字と同じです。

チェック情報

グループ: 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.