Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uwm.edu!dogie.macc.wisc.edu!uakari.primate.wisc.edu!ark1!nems!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: avoiding stdio Message-ID: <21968@mimsy.umd.edu> Date: 20 Jan 90 22:52:58 GMT References: <10883@attctc.Dallas.TX.US> <21689@mimsy.umd.edu> <28888@stealth.acf.nyu.edu> Distribution: na Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 72 In article <28888@stealth.acf.nyu.edu> brnstnd@stealth.acf.nyu.edu writes: >What Chris means is that in most cases, there is a definite disadvantage >in speed in avoiding buffering. There's also a definite disadvantage in >programmer time in rewriting all the standard libraries. There is also the problem that `appropriate buffering' can change with a new release of the system. For instance, the OS/2 file system is much like the BSD FFS in some ways, and there an advantage to using larger buffers (under older PC OSes, a `disk block' is smaller than under OS/2). >There is, however, a definite advantage in speed in using the facilities >of the operating system without stdio to get in the way. This can indeed happen, since stdio tends to do too much data copying: e.g., the loop while (fgets(s, n, rstream) != NULL) (void) fputs(s, wstream); works by reading from rstream to a buffer, copying the buffer into s, copying s into a buffer for wstream, and then writing to wstream. >By the way, Chris, will the new BSD stdio have a working putc(c,*f++)? The ANSI standard says that putc(c, *f++) is a no-no. As a side effect of being an inline function under gcc, however, it will happen to work there. This putc() handles full, line, and no buffering, and the macro is rather complicated. (__s stands for `stdio'; the __ version of putc exists so that it is easy to define a function version in the library.) [excerpt 1] * The following always hold: * * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), * _lbfsize is -_bufsize, else _lbfsize is 0 * if _flags&__SRD, _w is 0 * if _flags&__SWR, _r is 0 * * This ensures that the getc and putc macros (or inline functions) never * try to write or read from a file that is in `read' or `write' mode. * (Moreover, they can, and do, automatically switch from read mode to * write mode, and back, on "r+" and "w+" files.) * * _lbfsize is used only to make the inline line-buffered output stream * code as compact as possible. [excerpt 2] #ifdef __GNUC__ static __inline int __sputc(int _c, FILE *_p) { if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) return (*_p->_p++ = _c); else return (__swbuf(_c, _p)); } #else /* * This has been tuned to generate reasonable code on the vax using pcc */ #define __sputc(c, p) \ (--(p)->_w < 0 ? \ (p)->_w >= (p)->_lbfsize ? \ (*(p)->_p = (c)), *(p)->_p != '\n' ? \ (int)*(p)->_p++ : \ __swbuf('\n', p) : \ __swbuf((int)(c), p) : \ (*(p)->_p = (c), (int)*(p)->_p++)) #endif -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris