[Search for users]
[Overall Top Noters]
[List of all Conferences]
[Download this site]
Title: | Digital Fortran |
Notice: | Read notes 1.* for important information |
Moderator: | QUARK::LIONEL |
|
Created: | Thu Jun 01 1995 |
Last Modified: | Fri Jun 06 1997 |
Last Successful Update: | Fri Jun 06 1997 |
Number of topics: | 1333 |
Total number of notes: | 6734 |
1285.0. "passing CONSTANT to a subroutine" by HYDRA::LNARAYAN () Tue May 06 1997 15:05
Hello
When passing a constant to a subroutine from main, the subroutine gets
it as a floating point number. But when that constant is assigned to a
variable before passing it works fine.
The following example is from a partner, He is using FORTRAN to access
their database. Actually the subroutine ACCLOA is host language
interface routine, in which this is happening.
Thanks in advance
Lakshminarayan
---------------------------------------------------------------------------------
Joblog> RUN HT09241
INTEGER ERROR, TRACE, NEXT, HIFIT, INTNUM, DESGI, FI, RECADR
INTEGER ZERO, ONE, MONE, INT2, INT3, INT4, INT22, INT44, INT66
DOUBLE PRECISION DPNUM, FN, ZEROD, ONED
CHARACTER *20 DNAME, FC
REAL SPNUM
COMMON/ARGU/ FI, RECADR, fn, fc
ZERO = 0
ONE = 1
MONE = -1
INT2 = 2
INT3 = 3
INT4 = 4
INT22 = 22
INT44 = 44
INT66 = 66
---- Notice that %DESCR(1) in the above call has the constant one.
When executed it gives the following results
>> CALL ACCLOA(IN,TRACE,0,'@DBL_NAME','','@VERSION.NUMBER',RE,'@INTEGER',
>> UN,0,0,'@NUMBER',1,0,DP)
Expecting INTEGER argument - invalid argument type
Error in call #1 to subroutine ACCLOA at argument 9
>> RETURN(932)
When I change the 1 to ONE as below:
CALL ACCLOA(%DESCR(ERROR), %DESCR(TRACE), %DESCR(ZERO),
1 '@DBL_NAME', DNAME,
2 '@VERSION.NUMBER', %DESCR(SPNUM),
3 '@INTEGER',%DESCR(ONE),%DESCR(ZERO), %DESCR(INTNUM),
4 '@NUMBER',%DESCR(ONE),%DESCR(ZERO), %DESCR(DPNUM))
I get the correct results with no errors
>> CALL ACCLOA(IN,TRACE,0,'@DBL_NAME','','@VERSION.NUMBER',RE,'@INTEGER',
>> 1,0,0,'@NUMBER',1,0,DP)
>> RETURN(0)
DBL NAME=HT0924
INTEGER = 0
NUMBER = 0.0000000000000000
VERSION.NUMBER =12.06
As you can see, I changed all constants to variables to get it to work
correctly. (0 became ZERO, 1 became ONE, 2 became TWO, etc.).
ps: the following is what I used for compile and link
$ fortran/VMS/float=d_float/nodebug/optimize/nolist ht09241
$link ht09241,nis:accvax/lib,nis:acchli/lib
T.R | Title | User | Personal Name | Date | Lines |
---|
1285.1 | | QUARK::LIONEL | Free advice is worth every cent | Tue May 06 1997 15:11 | 8 |
| You haven't shown the declaration of the argument in routine ACCLOA, but
I'll bet that it's REAL. 1 is an INTEGER constant and if you pass it to
a routine expecting a REAL, you'll get wrong results. When you assign to ONE,
you convert it to REAL since ONE is (implicitly) REAL. Use 1.0 if you want
to specify a REAL constant with the value 1. (And if the argument is double
precision, use 1.0D0)
Steve
|
1285.2 | This subroutine always expect/assumes INTEGER | HYDRA::LNARAYAN | | Tue May 06 1997 16:08 | 10 |
| Steve
Thank You very much for the quick reply.
I understand that in the subroutine ACCLOA ( a C routine) it is always
expecting an INTEGER. So when an INTEGER is passwd from MAIN it works,
But when passed as a CONSTANT INTEGER it fails. The subroutine complains
that it is getting a REAL number. Any Ideas?
Thank You
Lakshminarayan
|
1285.3 | | QUARK::LIONEL | Free advice is worth every cent | Tue May 06 1997 16:17 | 19 |
| Ok, now I know what's happening. My apologies for not looking closer.
When you say %DESCR(1), the compiler passes 1 as a quadword integer and
puts DSC$K_DTYPE_Q in the descriptor. Your ACCLOA routine probably can't
handle that and assumes that if it's not integer, it's real. When you
explicitly pass ONE (which is declared INTEGER), you get DSC$K_DTYPE_L for
a longword integer.
If you do this instead:
INTEGER ONE
PARAMETER (ONE=1)
CALL ACCLOA (...%DESCR(ONE) ...
it will do what you want. I'm not aware of an easy way to force the datatype
of the literal 1 to longword.
Steve
|
1285.4 | this is a job for ... F90 90 90 90 90 | TLE::WHITLOCK | Stan Whitlock | Wed May 07 1997 10:24 | 18 |
| RE: .-1
>> INTEGER ONE
>> PARAMETER (ONE=1)
>> CALL ACCLOA (...%DESCR(ONE) ...
>> I'm not aware of an easy way to force the datatype of the literal 1 to
>> longword.
You could switch to f90 {did *I* say that?} and use
CALL ACCLOA (...%DESCR(1_4) ...)
F90 syntax allows a "kind" type after the constant: 1_4 is the integer constant
1 with integer kind=4 which is INTEGER*4.
/Stan
|
1285.5 | Is this correct? | HYDRA::LNARAYAN | | Thu May 08 1997 17:39 | 24 |
| Hello
Thanks for the suggestions.
Re .3, Please take a look at the feedback from the Partner given below.
I am having where DEC makes all integer constants integer*8 class.
This is not consistant with the OPEN VMS 32 bit environment.
If my tests are correct, even though you give it type 9 (DSC$K_DTYPE_Q)
you actually set it up as a 32 bit integer with the second 32 bits 0.
I declare an INTEGER*8 XYZ and set it to 11 with XYZ = 11
I then passed this to my ACCLOA routine, it came as type INTEGER*8
but when in the debugger with language c set I displayed it
with ex/longword and it output 11 indicating that in fact to was not
a quadword integer.
It would seem most reasonable to type constants as DSC$K_DTYPE_L
in a 32 bit environment.
|
1285.6 | | TLE::EKLUND | Always smiling on the inside! | Thu May 08 1997 18:49 | 21 |
| With Fortran 77 and separately compiled modules, a statement
of the form:
call foo(15)
MUST pass an integer-8 sized value for 15. That's because we might
be receiving the value in routine foo as:
subroutine foo(i)
integer*8 i
...
Anyway, that's what we think we implemented. Steve has merely given
you a way to get an integer*4 if you really, really need it at the
receiving end. This is one (of several) contexts where the compiler
does not have any way to determine the best size for the constant,
so we make what we hope is the "best" practical choice.
Cheers!
Dave Eklund
|
1285.7 | Wrong size doesn't lead to wrong values. | WIBBIN::NOYCE | Pulling weeds, pickin' stones | Fri May 09 1997 11:03 | 6 |
| One of the nice things about a little-endian system is that you can freely
pass integer constants that are "too large" and have the receiving end still
get "the right value". That's because the address points at the low-order
bits of the value. Your customer seems to believe that if we had passed a
quadword he would not have gotten the right value. That would be true for
a bit-endian system, but not for a little-endian one like Alpha or x86.
|