Versions Compared

Key

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

...

This code calls the getc() function with an expression as the stream argument. If getc() is implemented as a macro, the file may be opened several times (see FIO31-C. Do not simultaneously open the same file multiple times).

Code Block
bgColor#ffcccc
char *filename;
FILE *fptr;

/* initialize filename */

int c = getc(fptr = fopen(file_namefilename, "r"));
if (c == EOF) {
  /* Handle Error */
}

...

Code Block
bgColor#ccccff

int c;
char *filename;
FILE *fptr;

/* initialize filename */

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

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

...

In this non-compliant example, putc() is called with an expression as the stream argument. If putc() is implemented as a macro, the expression can be evaluated several times within the macro expansion of putc() with unintended results.

Code Block
bgColor#ffcccc

char *filename;
FILE *fptr = NULL;

/* initialize filename */

int c = 'a';
while (c <= 'z') {
  if (putc(c++, fptr ? fptr : 
       (fptr = fopen(file_namefilename, "w")) == EOF) {
    /* Handle Error */
  }
}

...

In the compliant solution, the stream argument to putc() no longer has side effects.

Code Block
bgColor#ccccff
char *filename;

/* initialize filename */

FILE *fptr = fopen(file_namefilename, "w");
if (fptr == NULL) {
  /* Handle Error */
}

int c = 'a';

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

...