How can "an expression with side effects" be passed to getc?

293 views Asked by At

"Advanced Programming in the UNIX Environment, 3rd Edition", page 151:

The difference between getc and fgetc is that getc can be implemented as a macro, whereas fgetc cannot be implemented as a macro. This means three things:

  • The argument to getc should not be an expression with side effects.
  • Since fgetc is guaranteed to be a function, we can take its address. This allows us to pass the address of fgetc as an argument to another function.
  • Calls to fgetc probably take longer than calls to getc, as it usually takes more time to call a function.

What "expression with side effects" can occur for the function signatures with stream pointer as a parameter?

#include<stdio.h>
int getc(FILE* stream);
int fgetc(FILE* stream);
2

There are 2 answers

3
Mat On BEST ANSWER

There are probably hundreds of ways to pass an expression with side effects, but a "credible" one would be something like:

FILE *files[NUM_FILES];
...
int rc = getc(files[counter++]);

If getc is implemented poorly as a macro, the expression files[counter++] could be evaluated more than once, leading to unexpected behavior.

3
Cheers and hth. - Alf On

As an example, don't write

FILE* foo() { puts( "Bah!\n" ); return stdout; }

void advance() { getc( foo() ); }