[fa.info-vax] DEC C

info-vax@ucbvax.ARPA (02/20/85)

From: Gail Rubin <grubin@bbn-spca>

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)

info-vax@ucbvax.ARPA (02/20/85)

From: Gene Lege' <ots!gene@rice.ARPA>


I would suggest using the varargs.h macros, or implementing
them if they are not available.  There is no other completely
portable way to pass a variable # of arguements to a "C" function,
other than simply defining the called function to accept a large
number of args and making sure you don't exceed this number.

For instance, on a Pyramid 90x running OSx (UNIX), some of the args
would be in the parameter registers, while others would be in the
(logical) extension of the stack that is actually in RAM.  The net
result is that the stack is seperated into two components, the
virtual addresses of which are non-contiguous.

I believe that the varargs.h standard will be sanctioned by
the forthcoming ANSI C standard.

I am glad to see this discussion of the DEC VMS C compiler.
We are working on a project that will need to run under both
UNIX and VMS;  Does anybody know of other pitfalls we should
watch out for while doing the development under UNIX?

info-vax@ucbvax.ARPA (02/21/85)

From: Jerry Leichter <Leichter@YALE.ARPA>

    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
-------

info-vax@ucbvax.ARPA (02/21/85)

From: Gail Rubin <grubin@bbn-spca>

Your information about the C standard and portability is reasonable
however, the particular application I am concerned with in my message is
one that is explicitly designed for VMS only. On the VAX, I KNOW what the
stack format is and since I don't use doubles as arguments, the number of
longwords IS the number of arguments.

My application is a package of routines, a run-time library of sorts, that
gets sent to customers and they write programs which call the routines.
Since I then have absolutely no control over whether my routines are called
correctly, or what language they are called from and some of the routines
do have optional arguments, I try to check the number of arguments as one
of my validity checks so I can give a more explicit error code back to the
user program instead of an access violation or strange behavior. I follow
calling standard behavior in that I never modify actual arguments;
basically all arguments are passed by reference or descriptor anyway.

In light of this, the behavior of DEC C 2.0 is
unsuitable for my application. I would be more inclined to stick with
the C I have rather than rewrite my routines in Macro.
-- Gail