Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker!spdcc!ima!haddock!karl From: karl@haddock.ima.isc.com (Karl Heuer) Newsgroups: comp.std.c Subject: Re: ANSI draft interpretation questions Message-ID: <15592@haddock.ima.isc.com> Date: 8 Jan 90 19:27:08 GMT References: <21623@mimsy.umd.edu> <11879@smoke.BRL.MIL> <21675@mimsy.umd.edu> <11897@smoke.BRL.MIL> <21690@mimsy.umd.edu> <15591@haddock.ima.isc.com> Reply-To: karl@haddock.ima.isc.com (Karl Heuer) Organization: Interactive Systems, Cambridge, MA 02138-5302 Lines: 32 As pointed out in my previous article, scanf() and ungetc() together require two lookahead/pushback slots. Personally, I'm surprised that the Committee did this. Providing a single slot is easy, as demonstrated by the traditional Unix implementation. It's not immediately obvious how to provide more than one, and still be able to provide the fast macro version of getc(). The solutions I've come up with can be easily generalized to more than two slots. So it appears that, given the insistence of the Committee to keep scanf() and ungetc() independent (despite common existing practice!), they could just as well have required scanf() to do full pushback for cases like "1.2e-x", which would require a total of four slots (three for scanf and one for ungetc), and not imposed any undue hardship on the implementation. There is a clause in the Standard that says that `all input takes place as if characters were read by successive calls to the |fgetc| function'. Of course |scanf| can't be written using only |fgetc| as a primitive, and I think it was probably a mistake to pretend that it can. My early suggestion was to add the clause `If an extra character is necessary to recognize the end of input, then scanf behaves as if it called the ungetc function after reading said character'. This would have kept the model simple, clearly documented the state of the stream following a scanf, and fixed the tricky implementation problem noted above. It would also have agreed with existing practice. Several months later I did find a way to implement |getc|, |ungetc|, and |scanf| so that they would follow the rules without incurring a substantial performance penalty. So my current opinion is that |scanf| should have been specified to do the morally correct thing, i.e. what Doug thought it was already specifying. Of course, it's too late to change it now. Karl W. Z. Heuer (karl@haddock.isc.com or ima!haddock!karl), The Walking Lint