View previous topic :: View next topic |
Author |
Message |
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Wed Jun 15, 2011 4:37 pm Post subject: Re: |
|
|
davidb wrote: | Actually, however, the Fortran standard doesn't say that arguments must be passed by reference, only that it must appear like that. |
Does the FORTRAN standard say that enclosing an argument in brackets "causes a temporary variable to be created which is passed by reference (usually)?" |
|
Back to top |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Wed Jun 15, 2011 6:10 pm Post subject: Re: |
|
|
sparge wrote: |
Does the FORTRAN standard say that enclosing an argument in brackets "causes a temporary variable to be created which is passed by reference (usually)?" |
I don't think the standard says this explicitly (I don't think I said it did). Its up to the compiler vendor how they implement passing of arguments.
If the vendor opts to pass by reference (most, maybe all, do), then they also need to provide a mechanism to deal with actual arguments which are:
(1) literal constants, e.g. call foo(10.0)
(2) Expressions, e.g. call foo(a*b+c)
(3) Array sections which are non contiguous in memory
Vendors can treat a single variable name in brackets as an expression if they wish and use whatever mechanism they have in place to deal with expressions, or they can ignore/remove the bracket and use the mechanism for passing a variable.
I was merely pointing out (above) that I can get around a bug in the compiler by putting an argument in brackets. I have no idea how this is working, however, given that
(1) Paul still hasn't confirmed there is a bug.
(2) Paul says FTN95 always passes by references, but I have some C++ code which receives a variable by value and I can manage to call it correctly. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7938 Location: Salford, UK
|
Posted: Thu Jun 16, 2011 7:16 am Post subject: |
|
|
I did not intend to imply that Quote: | FTN95 code always needs to pass values by reference to DLLs |
Subroutines in an FTN95 DLL can only admit/receive arguments that are passed by reference.
An FTN95 main program etc. can call subroutines in a third party dll (or an SCC dll) and in this situation the arguments can be sent/passed by value. |
|
Back to top |
|
|
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Thu Jun 16, 2011 9:47 am Post subject: Third time lucky? |
|
|
qt wrote: | ... the WinAPI/ODBC function SQLBindCol whose second argument requires a short unsigned integer to be passed ... |
(italics mine) Just reading this thread again ... FORTRAN has no concept of unsigned, I didn't register that keyword originally. I never understood the significance of the distinction in C i.e. I don''t understand how a compiler treats an integer differently depending if it is signed or unsigned ... but presumably that function would know and complain (or malfunction and suffer in silence) if it was passed a signed short integer from C code. Why would we expect it to work correctly if it gets a signed short integer from FORTRAN code? |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Thu Jun 16, 2011 12:32 pm Post subject: |
|
|
Surely an unsigned integer can give a value between 0 & 255 or 0 and 65535 depending on whether it is one byte or two byte version. The fortan 1 and two byte integers are signed, with the highest bit being the sign bit and can represent numbers between -128 and +127 or -32768 and +32767 respectively. If you want a single byte version, then use transfer or equivalence e.g.
Code: |
integer*2 itwobyte
integer*1 ionebyte(20)
equivalence (itwobyte,ionebyte)
!put a value into the two byte in the range 0 to 255
itwobyte = 255
!use the low byte which is an unsigned integer, but fotran will not treat it as such
!but you should be able to pass it to a C++ routine and that will treat it as unsigned.
print *,ionebyte(1)
|
The two byte unsigned version
Code: |
integer*4 ifourbyte
integer*3 itwobyte(20)
equivalence (ifourbyte,itwobyte)
!put a value into the four byte in the range 0 to 32767
ifourbyte = 32767
!use the low word which is an unsigned integer, but fotran will not treat it as such
!but you should be able to pass it to a C++ routine and that will treat it as unsigned.
print *,itwobyte(1)
|
and of course integer*8 and integer*4 if needed.
Ian
PS try the transfer method yourself - I still live in the ark! |
|
Back to top |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Thu Jun 16, 2011 12:39 pm Post subject: |
|
|
If we consider shorts (16 bit integers), the range of possible signed shorts is -32768 to 32767; whereas the range of possible unsigned shorts is 0 to 65535.
If you know your integers will always be zero or positive, and may exceed 32767 (but always be less than or equal too 65535) then you would use unsigned shorts. However, if you just want to loop over a list 1 to 1000 it would not matter which you use (aside from providing a visual clue to the programmer than an integer is non-negative).
I assume in the original DLL call the OP would just pass a signed integer of the appropriate value. To pass a value n > 32767, then a negative value
(32767 - n) would need to be passed.
PS. Or use Ian's equivalence method or transfer (but I would just use the subtraction method) |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7938 Location: Salford, UK
|
Posted: Tue Aug 02, 2011 11:25 am Post subject: |
|
|
My initial test for this issue is as follows
C function...
Code: | #include <stdio.h>
extern "C" void __stdcall PassIntegers(char i1Arg, short i2Arg, int i3Arg)
{
printf("%d\n", i1Arg);
printf("%d\n", i2Arg);
printf("%d\n", i3Arg);
} |
Fortran program...
Code: | program test
STDCALL PassIntegers 'PassIntegers'(VAL,VAL,VAL)
integer*1 i1
integer*2 i2
integer*4 i3
i1 = 7
i2 = 45
i3 = 19
call PassIntegers(i1,i2,i3)
end program test |
This works OK and I don't know how I can progress from here.
When you compile a function/subroutine using FTN95, arguments are always passed (in) by reference but you can pass arguments (out) by value from FTN95 when the function/subroutine is compiled using some other compiler such as SCC. |
|
Back to top |
|
|
dmcc_ies
Joined: 09 Dec 2011 Posts: 4
|
Posted: Fri Mar 02, 2012 11:47 am Post subject: |
|
|
When attempting to pass an int*2 (val, stdcall), does the ftn95 compiler simply promote this to an int*4 and pass this instead? |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7938 Location: Salford, UK
|
Posted: Fri Mar 02, 2012 5:03 pm Post subject: |
|
|
Yes. If you look at the /explist produced by program test above, then this appears to be the case. |
|
Back to top |
|
|
|