Versions Compared

Key

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

...

This non-compliant code example also violaties violates FIO33-C. Detect and handle input output errors resulting in undefined behavior because the value returned by fopen() is not checked for errors.

Compliant Solution: getc()

In this compliant solution, getc() is no longer called with an expression as its argument and the value returned by fopen() is checked for errors.

Code Block
bgColor#ccccff
FILE *fptr;
int c;

ifFILE ((*fptr = fopen(file_name, "r"));
if (fptr == NULL) {
  /* Handle Error */
}

if ((c = getc(fptr));
if (c == EOF) {
  /* Handle Error */
}

...

Code Block
bgColor#ffcccc
FILE *fptr = NULL;
int c = 'a';
while (c <= 'z') {
  if (putc(c++, fptr ? fptr : 
       (fptr = fopen(file_name, "w")) == EOF) 
  {
    /* Handle Error */
  }
}

If the putc() macro evaluates its stream argument multiple times, this might still seem safe, as the ?: operator ostensibly prevents multiple calls to fopen(). However, there is no guarantee that these would happen in distinct sequence points. Consequently this code also violates EXP30-C. Do not depend on order of evaluation between sequence points.

...

Code Block
bgColor#ccccff
FILE *fptr = fopen(file_name, "w");

if (fptr == NULL) {
  /* Handle Error */
}

int c = 'a';

while (c <= 'z') {
  if (putc(c++, fptr) == EOF) {
    /* Handle Error */
  }
}

...

This example only shows the side-effect issue. The output differs depending on the character set and one should . Consequently, it is important to not make assumptions about the order of the letters. For example, when run on a machine using an ASCII derived code set such as ISO-8859 or Unicode, this code sample will print out the 26 lower case letters of the English alphabet. However, if run with an EBCDIC based code set such as Codepage 037 or Codepage 285, punctuation marks marks or symbols might get printed out in may be output between the letters.

Risk Assessment

...