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.
Noncompliant Code Example
The following declaration of the signal()
function does not make use of typedef
names and is consequently hard to read.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 declaration of the signal()
function is difficult to read and comprehend:
Code Block | ||||
---|---|---|---|---|
| ||||
void (*signal | ||||
Code Block | ||||
| ||||
void (*SignalHandler(int, void (*)(int)))(int);
|
Compliant Solution
This compliant solution makes use of typedef
names type definitions to specify exactly the same type as in the non-compliant coding example.noncompliant code example:
Code Block | ||||
---|---|---|---|---|
| ||||
typedef void (*SignalHandler)SighandlerType(int signum); extern SignalHandlerSighandlerType *signal( int signum, SignalHandlerSighandlerType *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- |
1 (low)
1 (unlikely)
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" |
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 NCCE 2 DCL04-A. Take care when declaring more than one variable per declaration DCL06-A. Use meaningful symbolic constants to represent literal values in program logic