As getc() and putc() may be implemented as macros, calling them with parameters that have side effects may cause unexpected results, since the argument code could be evaluated multiple times.
Non-Compliant Code Example: getc()
This code calls the getc() function with an expression as an argument. If getc() is implemented as a macro expansion, the file may be opened several times (see FIO31-C. Do not simultaneously open a file multiple times).
char const *filename = "test.txt"; FILE *fptr; int c = getc(fptr = fopen(filename, "r"));
Compliant Solution: getc()
In this compliant solution, getc() is no longer called with an expression as its argument.
char const *filename = "test.txt"; FILE *fptr = fopen(filename, "r"); int c = getc(fptr);
Non-Compliant Code Example: putc()
In this non-compliant example, putc() is called with c++ as an argument. If putc() is implemented as a macro, c++ could be evaluated several times "within" putc(), causing unintended results.
char const *filename = "test.txt";
FILE *fptr = fopen(filename, "w");
int c = 97;
while(c < 123) {
putc(c++, fptr);
}
Compliant Solution: putc()
In the compliant solution, c++ is no longer an argument to putc().
char const *filename = "test.txt";
FILE *fptr = fopen(filename, "w");
int c = 97;
while(c < 123) {
putc(c, fptr);
c++;
}
Risk Assessment
Using an expression that has side effects as the argument to getc() or putc() could result in unexpected behavior.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
FIO41-C |
2 (medium) |
1 (low) |
2 (medium) |
P4 |
L3 |
References
[[ISO/IEC 9899-1999:TC2]] Section 7.19.7.5, "The getc function"; 7.19.7.8, "The putc function"