Main Content

CERT C: Rec. DCL23-C

Guarantee that mutually visible identifiers are unique

Description

Rule Definition

Guarantee that mutually visible identifiers are unique.1

Polyspace Implementation

The rule checker checks for these issues:

  • External identifiers not distinct.

  • Identifier in same scope and namespace not distinct.

  • Macro identifier not distinct.

  • Name for macros and identifiers not distinct.

Examples

expand all

Issue

The issue occurs when external identifiers have the same first six characters for C90 or the same first 31 characters for C99.

The checker does not flag this issue in a default Polyspace® as You Code analysis. See Checkers Deactivated in Polyspace as You Code Analysis (Polyspace Access).

Risk

External identifiers are ones declared with global scope or storage class extern.

Polyspace considers two names as distinct if there is a difference between their first 31 characters. If the difference between two names occurs only beyond the first 31 characters, they can be easily mistaken for each other. The readability of the code is reduced. For C90, the difference must occur between the first six characters. To use the C90 rules checking, use the value c90 for the option C standard version (-c-version).

Example - C90: First Six Characters of Identifiers Not Unique
int engine_temperature_raw;
int engine_temperature_scaled;   /* Non-compliant */					
int engin2_temperature;          /* Compliant */	

In this example, the identifier engine_temperature_scaled has the same first six characters as a previous identifier, engine_temperature_raw.

Example - C99: First 31 Characters of Identifiers Not Unique
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 */						

In this example, the identifier engine_exhaust_gas_temperature_scaled has the same first 31 characters as a previous identifier, engine_exhaust_gas_temperature_raw.

Example - C90: First Six Characters Identifiers in Different Translation Units Differ in Case Alone
/* file1.c */
int abc = 0;
/* file2.c */
int ABC = 0; /* Non-compliant */

In this example, the implementation supports six significant case-insensitive characters in external identifiers. The identifiers in the two translations are different but are not distinct in their significant characters.

Issue

The issue occurs when you declare identifiers in the same scope and namespace and the identifiers have the same first 31 characters in C90 or the same first 63 characters in C99.

Risk

Polyspace considers two names as distinct if there is a difference between their first 63 characters. If the difference between two names occurs only beyond the first 63 characters, they can be easily mistaken for each other. The readability of the code is reduced. For C90, the difference must occur between the first 31 characters. To use the C90 rules checking, use the value c90 for the option C standard version (-c-version).

Example - C90: First 31 Characters of Identifiers Not Unique
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 */
}

In this example, the identifier engine_exhaust_gas_temperature_scaled has the same 31 characters as a previous identifier, engine_exhaust_gas_temperature_raw.

The rule does not apply if the two identifiers have the same 31 characters but have different scopes. For instance, engine_exhaust_gas_temperature_local has the same 31 characters as engine_exhaust_gas_temperature_raw but different scope.

Example - C99: First 63 Characters of Identifiers Not Unique
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 */
}

In this example, the identifier engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_scale has the same 63 characters as a previous identifier, engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_raw.

Issue

The issue occurs when you use macro identifiers that have the same first 31 characters in C90 or the same first 63 characters in C99.

Risk

The names of macro identifiers must be distinct from both other macro identifiers and their parameters.

Polyspace considers two names as distinct if there is a difference between their first 63 characters. If the difference between two names occurs only beyond the first 63 characters, they can be easily mistaken for each other. The readability of the code is reduced. For C90, the difference must occur between the first 31 characters. To use the C90 rules checking, use the value c90 for the option C standard version (-c-version).

Example - C90: First 31 Characters of Macro Names Not Unique
#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 */

In this example, the macro engine_exhaust_gas_temperature_scaled egt_s has the same first 31 characters as a previous macro engine_exhaust_gas_temperature_scaled.

Example - C99: First 63 Characters of Macro Names Not Unique

#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 */

In this example, the macro engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx___gaz_scaled has the same first 63 characters as a previous macro engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx___raw.

Issue

The issue occurs when identifiers are not distinct from macro names.

Risk

The rule requires that macro names that exist only prior to processing must be different from identifier names that also exist after preprocessing. Keeping macro names and identifiers distinct help avoid confusion.

Polyspace considers two names as distinct if there is a difference between their first 63 characters. If the difference between two names occurs only beyond the first 63 characters, they can be easily mistaken for each other. The readability of the code is reduced. For C90, the difference must occur between the first 31 characters. To use the C90 rules checking, use the value c90 for the option C standard version (-c-version).

Example - Macro Names Same as Identifier Names
#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 */

In this example, Sum_1 is both the name of an identifier and a macro. Sum_2 is used only as a macro.

Example - C90: First 31 Characters of Macro Name Same as Identifier Name
#define	   low_pressure_turbine_temperature_1 lp_tb_temp_1
static int low_pressure_turbine_temperature_2;	  /* Non-compliant  */	

In this example, the identifier low_pressure_turbine_temperature_2 has the same first 31 characters as a previous macro low_pressure_turbine_temperature_1.

Check Information

Group: Rec. 02. Declarations and Initialization (DCL)

Version History

Introduced in 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.