Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site ucbvax.ARPA Path: utzoo!utcs!lsuc!pesnta!amdcad!decwrl!ucbvax!info-vax From: info-vax@ucbvax.ARPA Newsgroups: fa.info-vax Subject: Re: DEC C (2.0) Message-ID: <4975@ucbvax.ARPA> Date: Wed, 20-Feb-85 16:52:00 EST Article-I.D.: ucbvax.4975 Posted: Wed Feb 20 16:52:00 1985 Date-Received: Thu, 21-Feb-85 01:43:45 EST Sender: daemon@ucbvax.ARPA Organization: University of California at Berkeley Lines: 70 From: Jerry Leichter If you ever get a response to your SPR on the "address of arguments" problem, I would be interested in hearing about it. We currently use Whitesmith's C but we may decide to switch to DEC C, but not with this bug in it. I have one application that has a large number of routines which, as the first thing they do, is figure out how many arguments they were called with by taking the address of the first argument, subtracting 4, and using that as a pointer to the number of arguments. It sounds like DEC C version 2.0 would break this. [Is there some other "approved" way, from C, of determining number of arguments?] -- Gail Rubin (grubin@bbn-spca or @bbn-unix) a) Before you get too incensed about the "bug", find a reference anywhere in K&R, or in the proposed ANSI C standard, that says that arguments to a function are allocated sequentially in memory. I doubt you'll succeed. (If I remember right, the ANSI proposal includes some spec for a varargs facility; but this says nothing at all about the underlying mechanism.) The fact that an implementation happens to be different from pcc does not make it buggy. In fact, it's the code that uses a pcc implementation detail that is non- portable. (A look at K&R will reveal a discussion of what one may assume about memory layout - basically, that arrays and structures are layed out sequentially, but there may be gaps inside of structures - and an explicit warning that making any other assumptions is non-portable.) It's one thing to want a "pcc compatibility mode" in some other C compiler, quite another to claim that another C compiler is "buggy" if it doesn't match pcc in every one of its little quirks. b) There is no way (at all) to determine how many arguments a C function was called with. What you will find on the stack is a count of THE NUMBER OF WORDS (or is it bytes?) of arguments pushed. This corresponds in a direct way to the number of arguments only as long as you pass neither structures nor doubles. Once you do that, there is no way to make the translation without knowing the lengths of all the arguments. It's interesting to note, BTW, that the VAX Calling Standard requires all arguments to be longwords. Long floating point values, not to mention "big" objects like structures, are supposed to be passed by reference. However, the definition of C requires the ability to pass such things by immediate value, so the VAX C compiler is "given a variance". Programs in other languages don't support this extension; C programs using such calling sequences cannot call or be called by programs in other languages. (For example, you can use printf() from other languages - but not to print doubles.) BTW, nothing in K&R, or the ANSI draft spec, claims that a C function can determine how many arguments it was called with either. Some PDP-11 Unix versions had a nargs() function that worked by tracing back through the stack and examining the code at the point of call. This broke on machines with an I/D space split. The only effective way to do this is to pass the number of arguments as an additional argument - somewhere. That's what the VAX procedure call, in effect, does for you - as long as all your arguments are the same length. While handy, providing a count is not free and may be quite expensive on some machines; hence, for a low-level language like C, it's inappropriate to require it. I've always thought that the best approach would be to do this through the macro processor; that is, allow something like: #define f(a,b,#) real_f(#count,a,b,#) where "#" matches any number of additional arguments and #count is the actual count in the macro call being expanded. Trivial to implement, gives you the count when you need it and has no overhead when you don't need it. -- Jerry -------