Как передать "выражение с побочными эффектами" в getc?

"Расширенное программирование в среде UNIX, 3-е издание", стр. 151:

Разница между getc а также fgetc в том, что getc может быть реализован как макрос, тогда как fgetc не может быть реализовано как макрос. Это означает три вещи:

  • Аргумент к getc не должно быть выражением с побочными эффектами.
  • поскольку fgetc гарантированно будет функцией, мы можем взять ее адрес. Это позволяет нам передать адрес fgetc в качестве аргумента другой функции.
  • Звонки в fgetc вероятно, займет больше времени, чем звонки getc, так как обычно для вызова функции требуется больше времени.

Какое "выражение с побочными эффектами" может встречаться для сигнатур функций с указателем потока в качестве параметра?

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

2 ответа

Решение

Вероятно, есть сотни способов передать выражение с побочными эффектами, но "заслуживающий доверия" будет выглядеть примерно так:

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

Если getc плохо реализован как макрос, выражение files[counter++] может быть оценен более одного раза, что привело к неожиданному поведению.

В качестве примера не пишите

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

void advance() { getc( foo() ); }
Другие вопросы по тегам