Main Content

CERT C: Rec. DCL12-C

Implement abstract data types using opaque types

Description

Rule Definition

Implement abstract data types using opaque types.1

Polyspace Implementation

The rule checker checks for Structure or union object implementation visible in file where pointer to this object is not dereferenced.

Examples

expand all

Issue

The issue occurs when a pointer to a structure or union is never dereferenced within a translation unit, but the implementation of the object is not hidden.

If a structure or union is defined in a file or a header file included in the file, a pointer to this structure or union declared but the pointer never dereferenced in the file, the checker flags a coding rule violation. The structure or union definition should not be visible to this file.

If you see a violation of this rule on a structure definition, identify if you have defined a pointer to the structure in the same file or in a header file included in the file. Then check if you dereference the pointer anywhere in the file. If you do not dereference the pointer, the structure definition should be hidden from this file and included header files.

file.h: Contains structure implementation.

#ifndef TYPE_GUARD
#define TYPE_GUARD

typedef struct  {                                               
  int a;                                                    
} myStruct; 

#endif

file.c: Includes file.h but does not dereference structure.

#include "file.h"

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

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

In this example, the pointer to the type myStruct is not dereferenced. The pointer is simply obtained from the getObj function and passed to the useObj function.

The implementation of myStruct is visible in the translation unit consisting of file.c and file.h.

One possible correction is to define an opaque data type in the header file file.h. The opaque data type ptrMyStruct points to the myStruct structure without revealing what the structure contains. The structure myStruct itself can be defined in a separate translation unit, in this case, consisting of the file file2.c. The common header file file.h must be included in both file.c and file2.c for linking the structure definition to the opaque type definition.

file.h: Does not contain structure implementation.

#ifndef TYPE_GUARD
#define TYPE_GUARD

typedef struct myStruct *ptrMyStruct; 

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

#endif

file.c: Includes file.h but does not dereference structure.

#include "file.h"

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

file2.c: Includes file.h and dereferences structure.

#include "file.h"

struct myStruct {                                               
  int a;                                                    
};

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

Risk

If a pointer to a structure or union is not dereferenced in a file, the implementation details of the structure or union need not be available in the translation unit for the file. You can hide the implementation details such as structure members and protect them from unintentional changes.

Define an opaque type that can be referenced via pointers but whose contents cannot be accessed.

Example - Object Implementation Revealed

file.h: Contains structure implementation.

#ifndef TYPE_GUARD
#define TYPE_GUARD

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

#endif

file.c: Includes file.h but does not dereference structure.

#include "file.h"

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

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

In this example, the pointer to the type myStruct is not dereferenced. The pointer is simply obtained from the getObj function and passed to the useObj function.

The implementation of myStruct is visible in the translation unit consisting of file.c and file.h.

Correction — Define Opaque Type

One possible correction is to define an opaque data type in the header file file.h. The opaque data type ptrMyStruct points to the myStruct structure without revealing what the structure contains. The structure myStruct itself can be defined in a separate translation unit, in this case, consisting of the file file2.c. The common header file file.h must be included in both file.c and file2.c for linking the structure definition to the opaque type definition.

file.h: Does not contain structure implementation.

#ifndef TYPE_GUARD
#define TYPE_GUARD

typedef struct myStruct *ptrMyStruct; 

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

#endif

file.c: Includes file.h but does not dereference structure.

#include "file.h"

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

file2.c: Includes file.h and dereferences structure.

#include "file.h"

struct myStruct {                                               
  int a;                                                    
};

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

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.