Use Using type definitions (typedef
) to can often improve code readability. However, type definitions to pointer types can make it more difficult to write const
-correct code because the const
qualifier will be applied to the pointer type, not to the underlying declared type.
Non-Compliant Code Example
Noncompliant Code Example
The following type definition improves readability at the expense of introducing a const
-correctness issue. In this example, the const
qualifier applies to the typedef
instead of to the underlying object type. Consequently, func
does not take a pointer to a const struct obj
but instead takes a const
pointer to a struct obj
.
Code Block | ||||
---|---|---|---|---|
| ||||
struct obj {
int i;
float f;
};
typedef struct obj *ObjectPtr;
void func(const ObjectPtr o) {
/* Can actually modify o's contents, against expectations */
} |
Compliant Solution
This compliant solution makes use of type definitions but does not declare a pointer type and so cannot be used in a const
-incorrect manner:
Code Block | ||||
---|---|---|---|---|
| ||||
struct obj {
int i;
float f;
};
typedef struct obj Object;
void func(const Object *o) {
/* Cannot modify o's contents */
} |
Noncompliant Code Example (Windows)
The Win32 SDK headers make use of type definitions for most of the types involved in Win32 APIs, but this noncompliant code example demonstrates a const
-correctness bug:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <Windows.h>
/* typedef char *LPSTR; */
void func(const LPSTR str) {
/* Can mutate str's contents, against expectations */
} |
Compliant Solution (Windows)
This compliant solution demonstrates a common naming convention found in the Win32 APIs, using the proper const
type:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <Windows.h>
/* typedef const char *LPCSTR; */
void func(LPCSTR str) {
/* Cannot modify str's contents */
} |
Noncompliant Code Example (Windows)
Note that many structures in the Win32 API are declared with pointer type definitions but not pointer-to-const
type definitions (LPPOINT
, LPSIZE
, and others). In these cases, it is suggested that you create your own type definition from the base structure type.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <Windows.h>
/*
typedef struct tagPOINT {
long x, y;
} POINT, *LPPOINT;
*/
void func(const LPPOINT pt) {
/* Can modify pt's contents, against expectations */
} |
Compliant Solution (Windows)
Code Block | ||||
---|---|---|---|---|
| ||||
#include <Windows.h>
/*
typedef struct tagPOINT {
long x, y;
} POINT, *LPPOINT;
*/
typedef const POINT *LPCPOINT;
void func(LPCPOINT pt) {
/* Cannot modify pt's contents */
} |
Noncompliant Code Example
In this noncompliant code example, the The following declaration of the signal()
function is difficult to read and comprehend.:
Code Block | ||||
---|---|---|---|---|
| ||||
void (*signal(int, void (*)(int)))(int);
|
Compliant Solution
This compliant solution makes use of type definitions to specify the same type as in the non-compliant noncompliant code example.:
Code Block | ||||
---|---|---|---|---|
| ||||
typedef void (*SighandlerType)(int signum); extern SighandlerType *signal( int signum, SighandlerType *handler ); |
Exceptions
Function pointer types are an exception to this recommendation.
Risk Assessment
Code readability is important for discovering and eliminating vulnerabilities.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
DCL05- |
C |
Low |
Unlikely |
Medium | P2 | L3 |
Automated Detection
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| pointer-typedef | Fully checked | ||||||
Axivion Bauhaus Suite |
| CertC-DCL05 | |||||||
CodeSonar |
| LANG.STRUCT.PIT | Pointer type inside typedef | ||||||
Compass/ROSE | |||||||||
Helix QAC |
| C5004 | |||||||
LDRA tool suite |
| 299 S | Partially implemented | ||||||
Parasoft C/C++test |
| CERT_C-DCL05-a | Declare a type of parameter as typedef to pointer to const if the pointer is not used to modify the addressed object | ||||||
RuleChecker |
| pointer-typedef | Fully checked |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.7.7, "Type definitions"
\[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "BRS Leveraging human experience" |
Related Guidelines
CERT C Secure Coding Standard | DCL12-C. Implement abstract data types using opaque types |
SEI CERT C++ Coding Standard | VOID DCL05-CPP. Use typedefs to improve code readability |
...
DCL04-A. Do not declare more than one variable per declaration 02. Declarations and Initialization (DCL) DCL06-A. Use meaningful symbolic constants to represent literal values in program logic