Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utcs!mnetor!seismo!columbia!caip!brl-adm!brl-smoke!smoke!rbutterworth%watmath.waterloo.edu@CSNET-RELAY.ARPA From: rbutterworth%watmath.waterloo.edu@CSNET-RELAY.ARPA Newsgroups: net.lang.c Subject: Re: Yet another ALIGN idea. (some Message-ID: <2196@brl-smoke.ARPA> Date: Mon, 14-Jul-86 09:39:19 EDT Article-I.D.: brl-smok.2196 Posted: Mon Jul 14 09:39:19 1986 Date-Received: Mon, 14-Jul-86 22:31:58 EDT Sender: news@brl-smoke.ARPA Lines: 43 > From seismo!BRL.ARPA!gwyn Sat Jul 12 05:07:56 1986 > You say that an alignof(type) operator is required in order to > implement the va_arg(ap,type) macro. Could you please demonstrate > this? I don't believe it. Suppose we have a machine where sizeof(double)==8, sizeof(long)=8, sizeof(int)==4, alignof(double)==8, alignof(long)=4 alignof(int)==4. What does the macro va_arg(list,long) expand to? The token "long" can't be concatenated to form a predefined token such as "align_long" since it could just as easily have been "char *". So the only information we can really determine about the argument is by using sizeof(long). But this is simply 4 in this case. We still don't know where on the stack the argument will be. If it is a long (which we can't determine) it is at the next 4-byte boundary, but if it is a double (which it could just as easily be, given only its size) it is at the next 8-byte boundary. How is va_arg supposed to differentiate between these two cases? I didn't see anything in the standard restricting how things must be passed in the stack (e.g. all arguments must be aligned the same way (as in VAX BSD)). If there isn't an alignof() operator, some other built-in would be needed (e.g. newptr=align(oldptr,type)). Another example would be the case of structures. There is nothing that says that "struct{char a; char b;}" has to be aligned the same as "struct{double c;}", and I certainly don't see any way of making va_arg determine the alignment without a built-in alignof() operator. With a very strict reading of the standard one might decide that the "..." arguments can only be of type int, unsigned int, or double. That would certainly make my above examples invalid, but it would also make much less useful. If so, the standard could make this much clearer by changing The parameter _^Ht_^Hy_^Hp_^He is a type name such that the type of a pointer to an object that has the specified type can be obtained simply by postfixing a * to the type name. to The parameter _^Ht_^Hy_^Hp_^He must be "int", "unsigned int" or "double". or better yet, by replacing va_arg by three macros, va_int, va_unsigned, and va_double. I really don't think this was what was intended though.