Wie kann "ein Ausdruck mit Nebenwirkungen" an getc weitergegeben werden?

"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.

Was "Ausdruck mit Nebenwirkungen" kann für die Funktionssignaturen mit Stream-Zeiger als Parameter auftreten?

#include
int getc(FILE* stream);
int fgetc(FILE* stream);
0
Danke, BLUEPIXY, Jim Balter.
hinzugefügt der Autor Andrey Bushman, Quelle
ZB ch = getc (filePointerArray [++ i])
hinzugefügt der Autor BLUEPIXY, Quelle
getc (foo ()) wo FILE * foo() {/ * Nebenwirkungen * /} . getc (strptr ++) wobei FILE * strptr ist. getc (* pstrptr ++) wo FILE ** pstrptr . usw. Es ist wirklich einfach, Beispiele zu finden.
hinzugefügt der Autor Jim Balter, Quelle

2 Antworten

Als ein Beispiel, schreibe nicht

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

void advance() { getc( foo() ); }
0
hinzugefügt
Dieser Code funktioniert für mich. Fehler ist nicht aufgetreten.
hinzugefügt der Autor Andrey Bushman, Quelle
Ja, das "Bah!" wurde einmal für meinen gcc (version 4.8.1) gedruckt. Vielen Dank.
hinzugefügt der Autor Andrey Bushman, Quelle
@Bush Wie ist deine Antwort überhaupt relevant? Sie haben gefragt, wie ein Ausdruck mit Nebenwirkungen an getc übergeben werden kann, und dies ist eindeutig ein Beispiel. Der Text, den du zitierst, sagt "getc kann als Makro implementiert werden" - Ich weiß, dass Englisch nicht deine Muttersprache ist, aber du verstehst sicher, was "kann" bedeutet? Wenn Sie im Voraus angerufen haben und nicht mehr als ein "Bah!" gedruckt, dann ist die Version von getc, die Sie verwenden, kein Makro. (Sie können überprüfen, indem Sie auf stdio.h oder Makro suchen, indem Sie Ihre Quelle erweitern, z. B. mit gcc -
hinzugefügt der Autor Jim Balter, Quelle
@Bush: Abwesenheit der Garantie = Möglichkeit von Malf, nicht garantiert Malf
hinzugefügt der Autor Cheers and hth. - Alf, Quelle

Es gibt wahrscheinlich Hunderte von Möglichkeiten, einen Ausdruck mit Nebenwirkungen zu bestehen, aber ein "glaubwürdiger" wäre etwas wie:

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

Wenn getc als Makro schlecht implementiert ist, kann der Ausdruck files [counter ++] mehr als einmal ausgewertet werden, was zu unerwartetem Verhalten führt.

0
hinzugefügt
"schlecht"? "Ich bezweifle, dass eine vernünftige C-Bibliothek"? Du hast keine Ahnung wovon du sprichst. Die ursprüngliche stdio-Bibliothek und viele ihrer Nachkommen haben getc (f) als etwas wie - (f) -> ptr <(f) -> end? * (f) -> ptr ++: __getc (f) für Geschwindigkeit, weshalb getc ein Makro sein kann, das sein Argument neu bewertet.
hinzugefügt der Autor Jim Balter, Quelle
Machen Sie das - (f) -> cnt> 0? * (f) -> ptr ++: __getc (f)
hinzugefügt der Autor Jim Balter, Quelle
-1 re @JimBalter Anmerkung zu "Wenn getc als Makro schlecht implementiert ist, könnten die Ausdruck-Dateien [counter ++] mehr als einmal ausgewertet werden, was zu unerwartetem Verhalten führt. Ich bezweifle jedoch, dass irgendeine vernünftige C-Bibliothek einen solchen Fehler machen würde." . das ist eine gefährliche Desinformation, die man weitergeben kann.
hinzugefügt der Autor Cheers and hth. - Alf, Quelle