...
This does not apply to the character argument in putc(), which is guaranteed to be evaluated exactly once.
Non-Compliant Code Example
...
(getc
...
)
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).
...
This non-compliant code example also 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 | ||
|---|---|---|
| ||
int c;
char *file_name;
FILE *fptr;
/* initialize file_name */
fptr = fopen(file_name, "r");
if (fptr == NULL) {
/* Handle Error */
}
c = getc(fptr);
if (c == EOF) {
/* Handle Error */
}
|
Non-Compliant Code Example
...
(putc
...
)
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.
...
If the putc() macro evaluates its stream argument multiple times, this might still seem safe, as the ?: tertiary 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.
Compliant Solution
...
(putc
...
)
In the compliant solution, the stream argument to putc() no longer has side effects.
...