Prefer type definitions (typedef
) to macro definitions (#define
) when encoding types. Type definitions obey scope rules, whereas macro definitions do not. Type definitions can also correctly encode pointer types because they are not implemented as simple textual substitution. In this type definition, for example, the variable p
is declared as a constant pointer to char
[[Summit 05]]:
typedef char *NTCS; const NTCS p = &data;
This can be confusing to developers who think that type definitions are implemented using textual substitution. As a result, Dan Saks recommends placing type qualifiers as the rightmost declaration specifier when qualifying types [[Saks 99]]. While less confusing to some, this practice is not recommended because it is inconsistent with widely accepted practice and potentially misleading to experienced programmers.
Noncompliant Code Example
In this noncompliant code example, s1
is declared as char *
, but s2
is declared as a char
, which is probably not what the intention of the programmer intended.
#define cstring char * cstring s1, s2;
This noncompliant code example also violates DCL04-C. Do not declare more than one variable per declaration.
Compliant Solution
In this compliant solution, both s1
and s2
are declared as char *
.
typedef char * cstring; cstring s1, s2;
Risk Analysis
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
PRE03-C |
low |
unlikely |
medium |
P2 |
L3 |
Automated Detection
The LDRA tool suite V 7.6.0 can detect violations of this recommendation.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C++ Secure Coding Standard as PRE03-CPP. Prefer typedefs to defines for encoding types.
References
[[ISO/IEC 9899:1999]] Section 6.7, "Declarations"
[[ISO/IEC PDTR 24772]] "NMP Pre-processor Directives"
[[Saks 99]]
[[Summit 05]] Question 1.13, Question 11.11