...
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 | ||
|---|---|---|
| ||
char *filename; FILE *fptr; /* initialize filename */ int c = getc(fptr = fopen(file_namefilename, "r")); if (c == EOF) { /* Handle Error */ } |
...
| Code Block | ||
|---|---|---|
| ||
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 | ||
|---|---|---|
| ||
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 | ||
|---|---|---|
| ||
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 */ } } |
...