gnu@hoptoad.uucp (John Gilmore) (07/28/87)
Tonight I reimplemented the curses routine printw(), which used to call into the guts of stdio, using vsprintf(). I could not reimplement scanw() because there is apparently no vsscanf(). If not, why not? I looked both in the Sun documentation (Rel 3.3) and in the draft C standard. This seems like an obvious omission. Also, I noticed that the Sun documentation for varargs says: "The argument list (or its remainder) can be passed to another function using a pointer to a variable of type va_list -- in which case a call to va_arg in the subroutine advances the argument-list pointer with respect to the caller as well." On the other hand, vsprintf() wants the argument list passed as a variable of type va_list, not a pointer to such a variable. It is not clear what effect this has on the argument pointer, since the type of va_list is unknown, and vsprintf() doesn't document the effect. In the draft C standard, it specifies: "The type declared is va_list which is an array type... The variable ap may be passed as an argument to another function." (ap refers to the parameter declared as va_list.) If passed to another function, the array will be converted to a pointer, which presumably means that calls to va_arg in the subroutine would also advance the argument pointer, as documented in SunOS. The standard should specify this behaviour rather than leaving it to be inferred. (Actually the standard should standardize <varargs.h> rather than a newly invented, incompatible construction.) -- {dasys1,ncoast,well,sun,ihnp4}!hoptoad!gnu gnu@postgres.berkeley.edu Alt.all: the alternative radio of the Usenet.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/28/87)
In article <2545@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes: >... there is apparently no vsscanf(). If not, why not? I suspect mainly because the scanf() family are unsafe functions that are only provided because so much existing code already uses them. There is little interest in adding to that family. >In the draft C standard, it specifies: > "The type declared is va_list which is an array type... > The variable ap may be passed as an argument to another function." >(ap refers to the parameter declared as va_list.) If passed to another >function, the array will be converted to a pointer, which presumably >means that calls to va_arg in the subroutine would also advance >the argument pointer, as documented in SunOS. The standard should >specify this behaviour rather than leaving it to be inferred. The argument walker is stored in the array in the parent routine. The standard does not purport to be a tutorial. Generally it adds explanations only where it is felt there are grounds for confusion or misinterpretation. The whole point of requiring va_list to be an array type (and no other) is to make clear the exact semantics to be expected of ap. It would perhaps be appropriate to have words to this effect in the Rationale, but the Standard is unambiguous on this point. >(Actually the standard should standardize <varargs.h> rather than a newly >invented, incompatible construction.) That is uncalled for. I assure you that X3J11 does not go about changing things without good reason. They did start with <varargs.h>, but found that it was simply not suitable for the more rigorous ", ..." approach to variable argument lists, as well as to accommodate unusual CPU architectures. It is important to realize that it is only under a simple, uniform implementation such as most VAX and MC68000 C systems that the new X3J11 mechanisms duplicate existing functionality with no substantial change to the underlying mechanisms. In the more general setting, a variable-argument function is a NEW and DIFFERENT beast than what you have seen before. It may be implemented quite differently from a fixed-argument function. The <stdarg.h> mechanism is specifically designed to support this new and different beast, which in turn was introduced out of necessity (under some circumstances) to let the implementation know about the different essential nature of varargs functions. <stdarg.h> went through many design iterations before stabilizing in the form it now has (very slightly amended on 15-May-1987). I suspect that C implementations on the more trivial architectures will provide both <varargs.h> and <stdarg.h>, but the v*printf() functions have to know what type they're getting for ap, so they will no longer be usable with <varargs.h> va_list variables. The persistence of the names va_* reflects the evolution from <varargs.h> and is perhaps unfortunate at this point; for a while X3J11 was hoping to be able to guarantee full compatibility between the two approaches. Disclaimer: This is not to be construed as an official X3J11 response. Send public comments to Tom Plum; there is still some (slim) chance that the committee will consider them before the next public review even though it is way past the official comment period for the last public draft.