[comp.sys.apollo] function prototype mystery?

etb@milton.u.washington.edu (Eric Bushnell) (04/11/91)

I don't understand the argument declarations used
in the following function prototype. Could someone
give me a clue? I tried RTFM, with no luck.

I'm using the apollo system call proc2_$get_info(),
which is defined in proc2.h as:

void proc2_$get_info(
        uid_$t          &p2_uid,
        proc2_$info_t   *info,
        pinteger        &info_buf_len,  /* size of info buffer (bytes) */
        status_$t       *sts
);

What do the &'s do to the first and third arguments?
It looks to me like the function expects addresses, but if
I pass addresses to it, the compiler (cc 6.7.m, OS10.3) complains
that the argument type conflicts with the declaration.

What works is something like proc2_$get_info(p2_uid,&info,bufferlength,&status).Why? Is this some kind of apollo-ism, or something ANSI-like?

Thanks, as always

Eric Bushnell
UW Civil Engineering
etb@u.washington.edu


-- 
Eric Bushnell
Univ of Washington Civil Engineering
etb@zeus.ce.washington.edu
etb@milton.u.washington.edu

daifuku@yumyum.esd.sgi.com (Peter Daifuku) (04/12/91)

> void proc2_$get_info(
>         uid_$t          &p2_uid,
>         proc2_$info_t   *info,
>         pinteger        &info_buf_len,  /* size of info buffer (bytes) */
>         status_$t       *sts
> );
> 
> What do the &'s do to the first and third arguments?
> It looks to me like the function expects addresses, but if
> I pass addresses to it, the compiler (cc 6.7.m, OS10.3) complains
> that the argument type conflicts with the declaration.
> 
> What works is something like
proc2_$get_info(p2_uid,&info,bufferlength,&status).Why? Is this some
kind of > > apollo-ism, or something ANSI-like?

This one threw me for a loop too, when I first encoutered it.
It's actually a C++-ism, and thus an APOLLO enhancement to C. It allows you to
pass arguments by reference, without specifically passing the address.
Hence, the
caller sends p2_uid, as opposed to &p2_uid, and the callee can reference p2_uid
directly, instead of *p2_uid. Since the argument is being passed by reference,
any modifications by the callee are seen by the caller.


Peter Daifuku               Silicon Graphics
daifuku@sgi.com             Mountain View, CA 94039

----------------------------------------------------
Knowledge is power! Now, who said that?

thompson@PAN.SSEC.HONEYWELL.COM (John Thompson) (04/12/91)

<<forwarded message>>
> I don't understand the argument declarations used
> in the following function prototype. Could someone
> give me a clue? I tried RTFM, with no luck.
RTF C-Manual, section 3.16 (Reference Variables - Domain Extension)
 
> I'm using the apollo system call proc2_$get_info(),
> which is defined in proc2.h as:
> 
> void proc2_$get_info(
>         uid_$t          &p2_uid,
>         proc2_$info_t   *info,
>         pinteger        &info_buf_len,  /* size of info buffer (bytes) */
>         status_$t       *sts
> );
> 
> What do the &'s do to the first and third arguments?
> It looks to me like the function expects addresses, but if
> I pass addresses to it, the compiler (cc 6.7.m, OS10.3) complains
> that the argument type conflicts with the declaration.
A reference variable (from C++) (as I understand it) is basically a "pass in the most
convenient manner, but make sure that it's local" (equiv to 'IN' in Domain Pascal).
This allows the compiler to pass large structures by pointer without passing them
as modifiable arguments.  I assume that the compiler also handles making a local copy
for the receiving procedure.
What this means for you as a programmer is that, when you see an '&' in a prototype
declaration, you should be passing an object, and not a pointer to an object.  The
compiler will decide whether to actually pass the pointer, but if it does, it makes 
sure that the procedure treats it (gets it?) as a local structure, and not as a pointer
to your object.

> What works is something like proc2_$get_info(p2_uid,&info,bufferlength,&status).
Why?  Is this some kind of apollo-ism, or something ANSI-like?
Well, it's a 'Domain Extension', so it's definitely Apollo-ism.  I believe it conforms
to C++'s standard, so maybe it'll become standard?  (Ha!)

BTW: When we (another engineer) encountered problems in DDE with looking at reference
variables, HP/Apollo said that "well, that's an extension and you really shouldn't
be using it in the first place" -- even though the manual states that "reference variables
provide a clean syntax for passing arguments by reference."  Yet another case of HP (sorry
guys, but I blame you) screwing the Apollo customers.

-- jt --
John Thompson
Honeywell, SSEC
Plymouth, MN  55441
thompson@pan.ssec.honeywell.com

Me?  Represent Honeywell?  You've GOT to be kidding!!!

nazgul@alphalpha.com (Kee Hinckley) (04/13/91)

In article <1991Apr11.164655.17092@milton.u.washington.edu> etb@milton.u.washington.edu (Eric Bushnell) writes:
>What do the &'s do to the first and third arguments?
Pass by reference.  You hand it the object, *it* hands the address.

>What works is something like proc2_$get_info(p2_uid,&info,bufferlength,&status).Why? Is this some kind of apollo-ism, or something ANSI-like?
>
Standard ANSI C.

-- 
Alfalfa Software, Inc.          |       Poste:  The EMail for Unix
nazgul@alfalfa.com              |       Send Anything... Anywhere
617/646-7703 (voice/fax)        |       info@alfalfa.com

I'm not sure which upsets me more: that people are so unwilling to accept
responsibility for their own actions, or that they are so eager to regulate
everyone else's.

nazgul@alphalpha.com (Kee Hinckley) (04/13/91)

In article <1991Apr12.191106.11154@alphalpha.com> nazgul@alphalpha.com (Kee Hinckley) writes:
>>What works is something like proc2_$get_info(p2_uid,&info,bufferlength,&status).Why? Is this some kind of apollo-ism, or something ANSI-like?
>>
>Standard ANSI C.
My mistake.  Standard C++.  You can tell what *I've* been using :-).

-- 
Alfalfa Software, Inc.          |       Poste:  The EMail for Unix
nazgul@alfalfa.com              |       Send Anything... Anywhere
617/646-7703 (voice/fax)        |       info@alfalfa.com

I'm not sure which upsets me more: that people are so unwilling to accept
responsibility for their own actions, or that they are so eager to regulate
everyone else's.

beierl_c@apollo.HP.COM (Christopher Beierl) (04/16/91)

In article <1991Apr11.164655.17092@milton.u.washington.edu> etb@milton.u.washington.edu (Eric Bushnell) writes:
>I don't understand the argument declarations used
>in the following function prototype. Could someone
>give me a clue? I tried RTFM, with no luck.
>... 
>void proc2_$get_info(
>        uid_$t          &p2_uid,
>        proc2_$info_t   *info,
>        pinteger        &info_buf_len,  /* size of info buffer (bytes) */
>        status_$t       *sts
>);
>
>What do the &'s do to the first and third arguments?
>...
>What works is something like
>  proc2_$get_info(p2_uid,&info,bufferlength,&status).
>  Why? Is this some kind of apollo-ism, or something ANSI-like?

The relevant FM is the Domain C Language Reference, section
3.15 Reference Variables -- Domain Extension.  See also Chapter 7,
Cross-Language Communication, and Appendix E, Using std_$call, in
the same FM.

Domain/C has added reference variables as an extension (borrowed from
C++) in order to facilitate cross-language communications.  The problem
being addressed is that Pascal and FORTRAN both pass arguments by
reference, while C passes its arguments by value.

Prior to the addition of function prototypes and reference variables
in Domain/C, the std_$call mechanism was the only supported method
for cross-language communication.  For instance, the declaration for
proc2_$get_info() from /sys/ins/proc2.ins.c is:

    std_$call void proc2_$get_info();

When a call is made to a routine declared with std_$call the C compiler
automatically passes the address of all arguments, rather than their
value.  This makes it possible to make cross-language calls, but at
the expense of distorting the appearance of the call in C source code.
For example, since it is declared std_$call, a call to proc2_$get_info
would look something like this:

    proc2_$get_info(p2_uid, info, info_buf_len, status);

rather than the more "natural" way it would appear if it was actually
a C routine and didn't need the std_$call:

    proc2_$get_info(p2_uid, &info, info_buf_len, &status);

The addition of reference variables and prototypes (used in the *.h files)
allows us to use a less blunt tool than std_$call and indicate on a per
argument basis whether we need to transparently pass by reference.  Thus
with the proper prototype we can access Pascal and FORTRAN routines as if
the were written in C, and can use the more natural C calling conventions
in our C application programs.  This makes life MUCH easier for the C
programmer!

I strongly recommend that you make use of the *.h files with their
function prototypes and reference variables rather than the *.ins.c
files which use std_$call.

-Chris


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Christopher T. Beierl  Internet: beierl_c@apollo.HP.COM;beierl_c@apollo.com
 Apollo Computer, Inc.      UUCP: {mit-eddie,yale,uw-beaver}!apollo!beierl_c
 A Subsidiary of Hewlett-Packard                       Phone: (508) 256-6600

vinoski@apollo.HP.COM (Stephen Vinoski) (04/17/91)

In article <1991Apr11.164655.17092@milton.u.washington.edu> etb@milton.u.washington.edu (Eric Bushnell) writes:
>I'm using the apollo system call proc2_$get_info(),
>which is defined in proc2.h as:
>
>void proc2_$get_info(
>        uid_$t          &p2_uid,
>        proc2_$info_t   *info,
>        pinteger        &info_buf_len,  /* size of info buffer (bytes) */
>        status_$t       *sts
>);
>
>What do the &'s do to the first and third arguments?

That indicates that the arguments are to be passed by reference.  This
is a Domain/C extension borrowed from C++.  Domain/Pascal passes
arguments by reference by default, and this extension allows C and
Pascal to interface very easily, much easier than with the std_$call()
stuff from the pre-sr10 days.

>It looks to me like the function expects addresses, but if
>I pass addresses to it, the compiler (cc 6.7.m, OS10.3) complains
>that the argument type conflicts with the declaration.

You don't need to pass addresses.  The compiler will take care of
everything for you.  For instance, given this function:

  void incr(int &x)
  {
    x++;
  }

This function can be called like so:

  int j = 5;
  incr(j);

The variable j will now contain the value 6.  This can be done with
pointers:

  void incr(int *x)
  {
    (*x)++;
  }

but this version of incr() must be called like this:

  int j = 5;
  incr(&j);

Note, however, that unlike C++, Domain/C will not generate a temporary
in the case where a constant is passed by reference, so the following
will cause an access violation:

  incr(5);

A constant can safely be passed by reference if the function does not
modify its argument.

All of this is covered in section 5.3.2 of the Domain C Language
Reference (002093-A00) (that's where this example came from).


-steve
| Steve Vinoski  (508)256-0176 x5904       | Internet: vinoski@apollo.hp.com  |
| HP Apollo Division, Chelmsford, MA 01824 | UUCP: ...!apollo!vinoski         |
| "The price of knowledge is learning how little of it you yourself harbor."  |
|                                                    - Tom Christiansen       |