T.R | Title | User | Personal Name | Date | Lines |
---|
324.1 | and a pinch of Macro32 & *poof* | ANYWAY::GORDON | What happens after the fire? | Mon Sep 29 1986 23:37 | 85 |
| It is possible to implement optional arguments in VAX FORTRAN
if you're willing to cheat with a small macro routine (attached)
and none of your optional arguments are strings. The reason that
strings cannot be optional, is that the FORTRAN compiler always
allocates a static descriptor in the subroutine and copies the
descriptors off the arglist into the routines static storage WHETHER
OR NOT THE STRING IS EVER REFERENCED. Therefor, an omitted string
argument will always ACCVIO.
The Macro routine attached to the end of this note is call
ARGCOUNT. It should be called immediately upon entering the routine
and needs to be declared INTEGER. An example (from a real routine
of mine...):
Integer*4 function enable_out_of_band_AST
& ( Enable_Mask, AST_routine, channel )
*
* Calling Sequence:
*
* ret-status.wlc.v = Enable_Out_of_Band_AST( Enable_Mask.rlu.r,
* AST_routine.fzeml.v [, [Channel.ml.r]])
*
implicit integer*4 (a - z)
byte first/.true./, chann_arg_present
integer*2 chan
integer*4 Enable_Mask, AST_routine, channel, argcount, num_args
num_args = argcount()
chann_arg_present = (num_args .ge. 3 .and.
& %loc(channel) .ne. 0)
.
:
*
* Check for optional args and take action as required
*
if(chann_arg_present) channel = chan
.
:
You should get the idea... Send me mail ( {ISWISS/ANYWAY}::GORDON)
if you need more, or want some more complete routines. The Macro
routine follows...
-----------------------cut-----here-------------------------------
;---------------------------------------------------------------
.title ARGCOUNT -- Number of Arguments passed to caller
.ident \1-002\
; Douglas A. Gordon
; Arcon Corporation
; 5-Feb-1985
; Last Revision Date: Mon 24-Jun-85 08:30
;
; Functional Description:
;
; Function to return the number of arguments passed to the caller
; of this routine. This routine is really only useful from higher
; level languages.
;
; Calling Sequence:
;
; num-args.wl.v = ARGCOUNT()
;
; Formal Parameters:
;
; None
;
; Side Effects:
;
; Unpredictable results may result if this routine is called from
; a main program.
;
; Revision History:
;
; \1-002\ 24-Jun-1985 added Routine macro for psect compatibility.
;
; routine argcount, <> NOTE: I expanded the "routine" macro here
.psect _code, pic, usr, con, rel, lcl, shr, exe, rd, nowrt
.entry argcount, ^m<>
movl @8(fp), r0 ; Put previous call's arg count
ret ; into R0 and return
.end
|
324.2 | One from North of the border! | SHEILA::PUCKETT | Open the pod bay doors please HAL | Wed Oct 01 1986 01:39 | 35 |
| Gidday...
Here's one (after the FF)
.title NARGS - returns # of arguments & arg supplied
;
; numargs=NARGS() returns # of args in arg list to Fortran
;
; logical argsup
; flag=ARGSUP(narg) returns .true. if arg # (narg) was suppiled
; relies on non-passed args having 0 in arg list
;
.psect $code,pic,con,rel,lcl,shr,exe,rd,nowrt,long
;
.entry NARGS,0 ; dont save anything (r0,r1 temp)
movl fp,r1
addl s^#8,r1
movl (r1),r1 ; get old AP
movzbl (r1),r0 ; return # of args
ret
;
.entry ARGSUP,^m<r2,r3>
clrl r0
movl @4(ap),r3
movl fp,r1
addl s^#8,r1
movl (r1),r1 ; get old AP
movzbl (r1),r2 ; number of args suppiled is in R2
cmpl r3,r2 ; is arg off end of list?
bgtr 10$ ; yes, return .false.
tstl (r1)[r3] ; no, see if arg pointer zero?
beql 10$ ; yes, return .false.
incl r0 ; nonzero, return .true.
10$: ret
.end
|
324.3 | Be a software engineer, not a hacker... | TLE::BRETT | | Wed Oct 01 1986 10:37 | 47 |
| Do it PROPERLY and don't let these crocks annoy the people who are
going to have to be maintaining this stuff for the next twenty years
get stuck with your cleverness.
So what is PROPERLY here.
FORTRAN does NOT support optional parameters, and what it does before
it calls some "clever" hacker's messy .MAR subroutine is its business
and not yours. For example, it is quite entitled to move ALL of
the arguments into registers...
Since your subroutine must support optional parameters, you have
a choice of two languages, namely MACRO and BLISS. (Maybe PASCAL????).
Since your algorithm must be written in FORTRAN, it stands to reason
you need a JACKET ROUTINE, written in BLISS or MACRO, surrounding
your FORTRAN routine.
So, the proper solution is
routine JACKET(P1, P2, P3, P4,...) =
begin
builtin nullparameter;
local
REAL_P1, REAL_P2, ...;
REAL_P1 = default_p1_value;
if not nullparameter(P1) then REAL_P1 = .P1;
...
return FORTRAN_ROUTINE(.REAL_P1,...)
end;
Yes, this gets you an extra layer of CALL/RET. Yes, that is slower.
But does it *really* matter, or are you going to try and squeeze
an extra 0.01% performance out by putting some not-quaranteed-to-work
kludge in your product?
Furthermore, if performance is really that critical, look at providing
more than one FORTRAN subroutine offering the different combinations
of arguments.
/Bevin
|
324.4 | C Overlooked Yet Again | VAXUUM::DYER | Working For The Yankee Dollar | Wed Oct 01 1986 21:17 | 10 |
| > Since your subroutine must support optional parameters, you
> have a choice of two languages, namely MACRO and BLISS.
> (Maybe PASCAL????)
Once again, something is alleged to be feasible only with
MACRO and BLISS when C has no problem doing it. C's had varargs
capabilities for quite some time.
I believe VAX Pascal has default values for optional param-
eters. I don't know if it's standard Pascal or not . . .
<_Jym_>
|
324.5 | Give 'em what they ask for... | ANYWAY::GORDON | What happens after the fire? | Thu Oct 02 1986 09:03 | 8 |
| re: .3
.0 asked for a hack.... ;-}
... and I supplied one...
--Doug_who_used_to_be_a_customer_with_only_a_FORTRAN_compiler_and_who_-
did_many_perverse_and_hackish_things_in_FORTRAN_and_a_handful_of_MACRO.
|
324.6 | AP is just another register | STAR::BRANDENBERG | Civilization is the progress toward a society of privacy. | Tue Oct 07 1986 17:44 | 7 |
| There is another dangerous aspect of using variable arguments in
VAX Fortran and that is that the optimizer will, believe it or not,
grab the argument pointer if it thinks it is no longer needed (observed
on a VMS 3.5 system compiler version unknown). So, the best way
to avoid this is to compile /nooptimize.
Monty
|
324.7 | Tail between legs... | SHEILA::PUCKETT | Open the pod bay doors please HAL | Wed Oct 08 1986 20:14 | 3 |
| I have seen this behaviour on V4.5-219. So my hack won't work any more...
= Giles =
|