[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::fortran

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.RTitleUserPersonal
Name
DateLines
1285.1QUARK::LIONELFree advice is worth every centTue May 06 1997 15:118
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.2This subroutine always expect/assumes INTEGERHYDRA::LNARAYANTue May 06 1997 16:0810
    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.3QUARK::LIONELFree advice is worth every centTue May 06 1997 16:1719
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.4this is a job for ... F90 90 90 90 90TLE::WHITLOCKStan WhitlockWed May 07 1997 10:2418
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.5Is this correct?HYDRA::LNARAYANThu May 08 1997 17:3924
    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.6TLE::EKLUNDAlways smiling on the inside!Thu May 08 1997 18:4921
    	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.7Wrong size doesn't lead to wrong values.WIBBIN::NOYCEPulling weeds, pickin' stonesFri May 09 1997 11:036
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.