You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md
+145-2Lines changed: 145 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,9 +5,152 @@ This query implements the CERT-C rule DCL31-C:
5
5
> Declare identifiers before using them
6
6
7
7
8
-
## CERT
9
8
10
-
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py`**
9
+
## Description
10
+
11
+
The C11 Standard requires type specifiers and forbids implicit function declarations. The C90 Standard allows implicit typing of variables and functions. Consequently, some existing legacy code uses implicit typing. Some C compilers still support legacy code by allowing implicit typing, but it should not be used for new code. Such an [implementation](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) may choose to assume an implicit declaration and continue translation to support existing programs that used this feature.
12
+
13
+
## Noncompliant Code Example (Implicit int)
14
+
15
+
C no longer allows the absence of type specifiers in a declaration. The C Standard, 6.7.2 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\], states
16
+
17
+
> At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each `struct` declaration and type name.
18
+
19
+
20
+
This noncompliant code example omits the type specifier:
21
+
22
+
```cpp
23
+
extern foo;
24
+
25
+
```
26
+
Some C [implementations](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) do not issue a diagnostic for the violation of this constraint. These nonconforming C translators continue to treat such declarations as implying the type `int`.
27
+
28
+
## Compliant Solution (Implicit int)
29
+
30
+
This compliant solution explicitly includes a type specifier:
31
+
32
+
```cpp
33
+
externint foo;
34
+
35
+
```
36
+
37
+
## Noncompliant Code Example (Implicit Function Declaration)
38
+
39
+
Implicit declaration of functions is not allowed; every function must be explicitly declared before it can be called. In C90, if a function is called without an explicit prototype, the compiler provides an implicit declaration.
40
+
41
+
The C90 Standard \[[ISO/IEC 9899:1990](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-1990)\] includes this requirement:
42
+
43
+
> If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration `extern int identifier();` appeared.
44
+
45
+
46
+
If a function declaration is not visible at the point at which a call to the function is made, C90-compliant platforms assume an implicit declaration of `extern int identifier();`.
47
+
48
+
This declaration implies that the function may take any number and type of arguments and return an `int`. However, to conform to the current C Standard, programmers must explicitly prototype every function before invoking it. An implementation that conforms to the C Standard may or may not perform implicit function declarations, but C does require a conforming implementation to issue a diagnostic if it encounters an undeclared function being used.
49
+
50
+
In this noncompliant code example, if `malloc()` is not declared, either explicitly or by including `stdlib.h`, a compiler that conforms only to C90 may implicitly declare `malloc()` as `int malloc()`. If the platform's size of `int` is 32 bits, but the size of pointers is 64 bits, the resulting pointer would likely be truncated as a result of the implicit declaration of `malloc()`, returning a 32-bit integer.
51
+
52
+
```cpp
53
+
#include<stddef.h>
54
+
/* #include <stdlib.h> is missing */
55
+
56
+
intmain(void) {
57
+
for (size_t i = 0; i < 100; ++i) {
58
+
/* int malloc() assumed */
59
+
char *ptr = (char *)malloc(0x10000000);
60
+
*ptr = 'a';
61
+
}
62
+
return 0;
63
+
}
64
+
```
65
+
**Implementation Details**
66
+
67
+
When compiled with Microsoft Visual Studio 2013 for a 64-bit platform, this noncompliant code example will eventually cause an access violation when dereferencing `ptr` in the loop.
68
+
69
+
## Compliant Solution (Implicit Function Declaration)
70
+
71
+
This compliant solution declares `malloc()` by including the appropriate header file:
72
+
73
+
```cpp
74
+
#include <stdlib.h>
75
+
76
+
int main(void) {
77
+
for (size_t i = 0; i < 100; ++i) {
78
+
char *ptr = (char *)malloc(0x10000000);
79
+
*ptr = 'a';
80
+
}
81
+
return 0;
82
+
}
83
+
```
84
+
For more information on function declarations, see [DCL07-C. Include the appropriate type information in function declarators](https://wiki.sei.cmu.edu/confluence/display/c/DCL07-C.+Include+the+appropriate+type+information+in+function+declarators).
85
+
86
+
## Noncompliant Code Example (Implicit Return Type)
87
+
88
+
Do not declare a function with an implicit return type. For example, if a function returns a meaningful integer value, declare it as returning `int`. If it returns no meaningful value, declare it as returning `void`.
89
+
90
+
```cpp
91
+
#include<limits.h>
92
+
#include<stdio.h>
93
+
94
+
foo(void) {
95
+
return UINT_MAX;
96
+
}
97
+
98
+
int main(void) {
99
+
long long int c = foo();
100
+
printf("%lld\n", c);
101
+
return 0;
102
+
}
103
+
104
+
```
105
+
Because the compiler assumes that `foo()` returns a value of type `int` for this noncompliant code example, `UINT_MAX` is incorrectly converted to `−1`.
106
+
107
+
## Compliant Solution (Implicit Return Type)
108
+
109
+
This compliant solution explicitly defines the return type of `foo()` as `unsigned int`. As a result, the function correctly returns ` `UINT_MAX` `.
110
+
111
+
```cpp
112
+
#include <limits.h>
113
+
#include <stdio.h>
114
+
115
+
unsigned int foo(void) {
116
+
return UINT_MAX;
117
+
}
118
+
119
+
int main(void) {
120
+
long long int c = foo();
121
+
printf("%lld\n", c);
122
+
return 0;
123
+
}
124
+
125
+
```
126
+
127
+
## Risk Assessment
128
+
129
+
Because implicit declarations lead to less stringent type checking, they can introduce [unexpected](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-unexpectedbehavior) and erroneous behavior. Occurrences of an omitted type specifier in existing code are rare, and the consequences are generally minor, perhaps resulting in [abnormal program termination](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-abnormaltermination).
Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-vulnerability) resulting from the violation of this rule on the [CERT website](https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+DCL31-C).
142
+
143
+
## Related Guidelines
144
+
145
+
[Key here](https://wiki.sei.cmu.edu/confluence/display/c/How+this+Coding+Standard+is+Organized#HowthisCodingStandardisOrganized-RelatedGuidelines) (explains table format and definitions)
146
+
147
+
<table> <tbody> <tr> <th> Taxonomy </th> <th> Taxonomy item </th> <th> Relationship </th> </tr> <tr> <td> <a> CERT C Secure Coding Standard </a> </td> <td> <a> DCL07-C. Include the appropriate type information in function declarators </a> </td> <td> Prior to 2018-01-12: CERT: Unspecified Relationship </td> </tr> <tr> <td> <a> ISO/IEC TR 24772:2013 </a> </td> <td> Subprogram Signature Mismatch \[OTR\] </td> <td> Prior to 2018-01-12: CERT: Unspecified Relationship </td> </tr> <tr> <td> <a> MISRA C:2012 </a> </td> <td> Rule 8.1 (required) </td> <td> Prior to 2018-01-12: CERT: Unspecified Relationship </td> </tr> </tbody> </table>
0 commit comments