The C Standard defines a set of predefined macros (see subclause 6.10.8) to help the user determine if the implementation being used is a conforming implementation, and if so, to which version of the C Standard it conforms. These macros can also help the user to determine which of the standard features are implemented.
The following tables below list these macros and indicate in which version of the C Standard they were introduced. The following macros are required:
Macro nameName | C90 | C99 | C11 |
---|---|---|---|
| ✓ | ✓ | ✓ |
|
| ✓ | ✓ |
|
| ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
...
The following are optional environment macros:
Macro nameName | C90 | C99 | C11 |
---|---|---|---|
|
| ✓ | ✓ |
|
| ✓ | ✓ |
|
|
| ✓ |
|
|
| ✓ |
The The following are optional feature macros:
Macro nameName | C90 | C99 | C11 |
---|---|---|---|
|
|
| ✓ |
|
| ✓ | ✓ |
|
| ✓ | ✓ |
|
|
| ✓ |
|
|
| ✓ |
|
|
| ✓ |
|
|
| ✓ |
|
|
| ✓ |
...
The following is optional and is defined by the user:
Macro nameName | C90 | C99 | C11 |
---|---|---|---|
__STDC_WANT_LIB_EXT1__ | ✓ |
Noncompliant Code Example (Checking
...
Value of
...
Predefined Macro)
C Standard predefined macros should never be tested for a value before the macro is tested for definition, as shown in this noncompliant code example:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> int main(void) { #if (__STDC__ == 1) printf("Implementation is ISO-conforming.\n"); #else printf("Implementation is not ISO-conforming.\n"); #endif /* ... */ return 0; } |
Compliant Solution (Testing for
...
Definition of
...
Macro)
In this compliant solution, the definition of the predefined macro __STDC__
is tested before the value of the macro is tested:
...
This compliant solution tests to see if the C11 predefined macro __STDC_ANALYZABLE__
is defined and what value the implementation has given the macro:
...
This compliant solution checks for the C11 optional language features in Annex K. If If Annex K is supported by the implementation, the functions defined in Annex K are used, ; if Annex K is not supported, then the Standard standard library functions are used. (See DCL09-C. Declare functions that return errno with a return type of errno_t.)
Code Block | ||||
---|---|---|---|---|
| ||||
#if defined(__STDC_LIB_EXT1__) #if (__STDC_LIB_EXT1__ >= 201112L) #define USE_EXT1 1 #define __STDC_WANT_LIB_EXT1__ 1 /* wantWant the ext1 functions */ #endif #endif #include <string.h> #include <stdlib.h> int main(void) { char source_msg[] = "This is a test."; char *msg = malloc(sizeof(source_msg) + 1); if (msg != NULL) { #if defined(USE_EXT1) strcpy_s(msg, sizeof msg, source_msg); #else strcpy(msg, source_msg); #endif } else { return EXIT_FAILURE; } return 0; } |
Risk Assessment
Not testing for language features , or the version of the implementation being used can lead to unexpected or undefined program behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
PRE13-C | lowLow | probableProbable | lowLow | P6 | L2 |
Related Vulnerabilities
...