You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

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"

  • No labels