Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Macro NameC90C99C11

__STDC__

__STDC_HOSTED__

 

__STDC_VERSION__1

 

__DATE__

__FILE__

__LINE__

__TIME__

  1) __STDC_VERSION__ was introduced by an Amendment to C90, this version of the C Standard is commonly call C94 

 The following are optional environment macros:

...

Macro NameC90C99C11
__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
bgColor#FFcccc
langc
#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:

Code Block
bgColor#ccccff
langc
#include <stdio.h>

int main(void) {
  #if defined(__STDC__)
    #if (__STDC__ == 1)
      printf("Implementation is ISO-conforming.\n");
    #else
      printf("Implementation is not ISO-conforming.\n");
    #endif
  #else   /* !defined(__STDC__) */
    printf("__STDC__ is not defined.\n");
  #endif
  /* ... */
  return 0;
}

Compliant Solution (Test for Optional feature)

This compliant solution tests to see if the C11 predefined macro __STDC_ANALYZABLE__ is defined and what value the implementation has given the macro:

Code Block
bgColor#ccccff
langc
#include <stdio.h>
 
int main(void) {
  #if defined (__STDC__)
    #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)  /* C11 */
      #if defined(__STDC_ANALYZABLE__)
        #if (__STDC_ANALYZABLE__ == 1)
	      printf("Compiler conforms to Annex L (Analyzability).\n");
        #else
	      printf("Compiler does not support Annex L (Analyzability).\n");
        #endif
      #else
        printf("__STDC_ANALYZABLE__ is not defined.\n");
      #endif
    #else
      printf("Compiler not C11.\n");
    #endif
  #else
    printf("Compiler not Standard C.\n");
  #endif
 
  return 0;
}

Compliant Solution (Optional Language Features)

This compliant solution checks for the C11 optional language features in Annex K. 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 library functions are used. (See DCL09-C. Declare functions that return errno with a return type of errno_t.)

Code Block
bgColor#ccccff
langc
#if defined(__STDC_LIB_EXT1__)
  #if (__STDC_LIB_EXT1__ >= 201112L)
    #define USE_EXT1 1
    #define __STDC_WANT_LIB_EXT1__ 1 /* Want 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

Low

Probable

Low

P6

L2

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

ISO/IEC TR 24772:2013Pre-processor Directives [NMP]
[ISO/IEC 9899:2011]

6.10.8, "Predefined macro names"

K.3.7.1, "Copying functions"

...