Как передать "выражение с побочными эффектами" в 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() ); }