brett@wjvax.UUCP (Brett Galloway) (07/29/86)
I have a complaint about the a shortcoming of the standard varargs package (to allow use of variable nos. of arguments). The varargs package uses a line of the form var = va_arg(va,<type>) to grab the next (variable) argument, where va is the variable argument pointer maintained by the varargs package, and <type> is the type of the next argument. The problem is related to C's argument promotion; namely, that it promotes char and short arguments to int's and float to double. Because the varargs package is a macro package, an expression of the form var = va_arg(va,short) fails, because, even if the caller tried to pass a short, it got converted to an int, and the va_arg macro will fail because it will not pick up all the bits of the int (assuming (sizeof(short) < sizeof(int))). So far, this is not deadly; you just remember never to have variable arguments that are "promotable"; i.e., always use int's or double's. The problem appears when you use a typedef. Depending on whether the typedef was promotable or not, a variable argument of the type will or will not fail. For example, I may do the following: typedef int NUMBER; ... NUMBER val; ... foo(val); ... foo(va_alist) va_dcl ... NUMBER value; ... value = va_arg(va,NUMBER); the latter part of this fragment is a function foo() with a variable argument of type NUMBER. If, in fact, NUMBER was an int, this will work. If NUMBER was a short, it will fail. This makes the typedef completely useless. To fix this problem, I propose a promote() operator, as follows: "promote(char)" => "int" "promote(short)" => "int" "promote(int)" => "int" "promote(float)" => "double" "promote(NUMBER)" => <whatever NUMBER typedef'd as> etc. An operator like this is REQUIRED to write a varargs package that works with typedef'd types. Note that there is NO way to emulate promote() with a macro. -- ------------- Brett Galloway {pesnta,twg,ios,qubix,turtlevax,tymix,vecpyr,certes,isi}!wjvax!brett
rbj@icst-cmr (Root Boy Jim) (07/29/86)
This makes the typedef completely useless. Only for varargs use. You can always have *two* typedefs, one for definitions, and one for argument declarations. I know, yuk! To fix this problem, I propose a promote() operator, as follows: Clearly, as you say, there is no way to emulate this. On the other hand, this is done so rarely as to be tolerated the way it is. Do you really want to muck up the language with rarely used constructs? As a side issue, routines requiring varargs are frowned on anyway. (Root Boy) Jim Cottrell <rbj@icst-cmr.arpa> On the road, ZIPPY is a pinhead without a purpose, but never without a POINT.
brett@wjvax.UUCP (Brett Galloway) (07/30/86)
Doug Gwyn <seismo!BRL.ARPA!gwyn> sent me E-mail responding to my posting about the need for a promote() operator to implement varargs. Unforunately, our mailer is broken, so I cannot respond privately. In any event, I believe that his response is of interest: >This is the second such suggestion in recent weeks. >I think we should be careful to distinguish between what the >application code/programmer sees for an interface and >what the C runtime implementer needs for his implementation. ><varargs.h> can be used safely if the programmer specifies >the correct (possibly widened) type and if he restricts himself >to the simpler data types. X3J11 has designed <stdarg.h> to >replace <varargs.h>, but there is still room for debate about >the current design. >Statements such as "<varargs.h> cannot be implemented without >a promote() or alignof() operator" are simply false. The >existence of such operators would not even be sufficient for some >architectures. Rather than specify such fine-grained details >of use only for implementing varargs, X3J11 is leaving it up >to the implementor how he pulls this trick, and is specifying >only the application code/programmer visible interface. If >this interface is properly designed, it will be implementable >"somehow" on every significant architecture (although perhaps >not purely in C). As might be guessed, I disagree. Of course, varargs can be implemented without a promote() or alignof() operator; it is so implemented now. However, it imposes the restrictions that Doug cites: "if the programmer specifies the correct (possibly widened) type and if he restricts himself to the simpler data types." I argue that a promote() operator is necessary to remove these restrictions. My article referred to using typedef'd types in varargs, and, in fact, without a promote() operator, using typedef'd types in varargs is impossible. Note that promote() is a necessary condition; not a sufficient condition. In short, I believe that X3J11, by omitting the (normally invisible) promote() operator, is forcing itself to limit the usefulness of the (visible) stdarg interface. -- ------------- Brett Galloway {pesnta,twg,ios,qubix,turtlevax,tymix,vecpyr,certes,isi}!wjvax!brett
brett@wjvax.UUCP (Brett Galloway) (07/31/86)
In article <2640@brl-smoke.ARPA> version B 2.10.3 4.3bsd-beta 6/6/85; site wjvax.wjvax.UUCP wjvax!qubix!saber!sun!decwrl!pyramid!hplabs!tektronix!uw-beaver!cornell!rochester!seismo!lll-crg!caip!brl-adm!brl-smoke!smoke!rbj@icst-cmr rbj@icst-cmr (Root Boy Jim) writes: >> This makes the typedef completely useless. >Only for varargs use. You can always have *two* typedefs, one for >definitions, and one for argument declarations. I know, yuk! >> To fix this problem, I propose a promote() operator, as follows: >Clearly, as you say, there is no way to emulate this. On the other hand, >this is done so rarely as to be tolerated the way it is. Do you really >want to muck up the language with rarely used constructs? > >As a side issue, routines requiring varargs are frowned on anyway. This is probably a question of varargs' role more than anything else. I find varargs useful, and therefor use it. When I do, I find the restriction that the user know about argument type promotion annoying, especially since the compiler knows about type promotion already. Apparently, you find varargs a kludge (you frown on it), and so label an enhancement to C that would generalize variable argument parsing "mucking up" the language. Presumably, since varargs is being standardized (as stdarg), the X3J11 committee finds it to be a feature and not a kludge. In that case, now is the time to generalize the stdarg interface, and that requires (a) new operator(s) in C. -- ------------- Brett Galloway {pesnta,twg,ios,qubix,turtlevax,tymix,vecpyr,certes,isi}!wjvax!brett