...
| Code Block | ||
|---|---|---|
| ||
char *file_name;
FILE *fptr;
/* initialize file_name */
int c = getc(fptr = fopen(file_name, "r"));
if (c == EOF) {
/* Handle Errorerror */
}
|
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.
...
| Code Block | ||
|---|---|---|
| ||
int c;
char *file_name;
FILE *fptr;
/* initialize file_name */
fptr = fopen(file_name, "r");
if (fptr == NULL) {
/* Handle Errorerror */
}
c = getc(fptr);
if (c == EOF) {
/* Handle Errorerror */
}
|
Non-Compliant Code Example (putc)
...
| Code Block | ||
|---|---|---|
| ||
char *file_name;
FILE *fptr = NULL;
/* initialize file_name */
int c = 'a';
while (c <= 'z') {
if (putc(c++, fptr ? fptr :
(fptr = fopen(file_name, "w")) == EOF) {
/* Handle Errorerror */
}
}
|
If the putc() macro evaluates its stream argument multiple times, this might still seem safe, as the ternary conditional expression 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 | ||
|---|---|---|
| ||
char *file_name;
/* initialize file_name */
FILE *fptr = fopen(file_name, "w");
if (fptr == NULL) {
/* Handle Errorerror */
}
int c = 'a';
while (c <= 'z') {
if (putc(c++, fptr) == EOF) {
/* Handle Errorerror */
}
}
|
The c++ is perfectly safe, because putc() guarantees to evaluate its character argument exactly once.
...