You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

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 tables below list these macros and which version of the C Standard they were introduced. The following macros are required in C11.

__STDC__

C89

C99

C11

__STDC_HOSTED__

 

 C99

C11

__STDC_VERSION__

(C94)

C99

C11

__DATE__

C89

C99

C11

__FILE__

C89

C99

C11

__LINE__

C89

C99

C11

__TIME__

C89

 C99

C11

  

 The following are optional environment macros in C11.

__STDC_ISO_10646__

 

C99

C11

__STDC_MB_MIGHT_NEQ_WC__

 

C99

C11

__STDC_UTF_16__

 

 

C11

__STDC_UTF_32__

 

 

C11

  

 The following are optional feature macros in C11.

__STDC_ANALYZABLE__

 

 

C11

__STDC_IEC_559__

 

C99

C11

__STDC_IEC_559_COMPLEX__

 

C99

C11

__STDC_LIB_EXT1__ 

 

 

 C11

__STDC_NO_ATOMICS__

 

 

C11

__STDC_NO_COMPLEX__

 

 

C11

__STDC_NO_THREADS__

 

 

C11

__STDC_NO_VLA__ 

 

 

C11

 

 The following is optional in C11 and is defined by the user:

__STDC_WANT_LIB_EXT1__    C11

Noncompliant Code Example (Checking value of predefined macro)

The value a C Standard predefined macro should never be tested for a value before the macro is tested to make sure it is defined, as shown in this noncompliant code example:

#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 example, the definition of the predefined macro __STDC__ is tested before the value of the macro is tested:

#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)

The follow example tests to see if the C11 predefined macro __STDC_ANALYZABLE__  defined and what value the implementation has given the macro:

#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)

The following example 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.)

#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"

 


  

  • No labels