* fortran 90 passing user defined type member to a c fucntion
@ 2010-03-26 22:02 burlen
2010-03-27 6:28 ` Ian Lance Taylor
0 siblings, 1 reply; 6+ messages in thread
From: burlen @ 2010-03-26 22:02 UTC (permalink / raw)
To: gcc-help
When calling a c function from a fortran 90 program with members of a
user defined types for output arguments of the called subroutine the
user defined types aren't being modified as they should be (according to
my understanding). But if I pass in native types (eg integer), these are
modified upon return as expected. So for the user defined types it's
behaving like pass by value, rather than pass by reference. The c
function has no interface defined, it's just linked in, so in my
understanding all arguments should be treated like intent inout, and I
think that means pass by reference. Am I correct in thinking that all
arguments passed to the c function should be passed by reference?
An example of passing the user defined type members to a fortran
subroutine showed that modifications of the arguments inside the
subroutine are visible to the caller when the subroutine returns. Which
is what I expected. There must be something about calling the c function
that changes the behavior.
Am I overlooking something simple here? If not, can someone explain why
the user defined type members are passed by value?
Thanks
Burlen
Here is an excerpt of the code:
module CartesianDecompModule
use BoxModule
!============================================================================
type CartesianDecomp
integer WorldRank ! my rank in comm world
integer WorldSize ! number of processes in the communicator
!----------------------------
integer Comm ! optimized cartesian communicator
logical Periodicity(3) ! periodic BC flags
logical Reorder ! if set optimize the communicator
integer NDims ! dimensionality (1,2, or 3)
integer NSubDomains(3) ! number of sub-domains
integer SubDomainCoords(3) ! index space coordinates into decomp
type(Box) Domain ! simulation domain
type(Box) SubDomain ! local portion of the domain
end type CartesianDecomp
contains
!----------------------------------------------------------------------------
subroutine CreateCommunicator(c)
use mpi
implicit none
type(CartesianDecomp) :: c ! object to initialize
integer :: iErr
integer :: comm,nsubs(3),subs(3)
! ! This doesn't work. output arguments
c%NSubDomains,c%Comm,c%SubDomainCoords, aren't modified ??
! call MPI_Dims_create(c%WorldSize,c%NDims,c%NSubDomains,iErr)
! call
MPI_Cart_create(MPI_COMM_WORLD,c%NDims,c%NSubDomains,c%Periodicity,c%Reorder,c%Comm,iErr)
! call
MPI_Cart_get(c%Comm,c%NDims,c%NSubDomains,c%Periodicity,c%SubDomainCoords,iErr)
! This works.
subs(:)=0
nsubs(:)=0
call MPI_Dims_create(c%WorldSize,c%NDims,nsubs,iErr)
call
MPI_Cart_create(MPI_COMM_WORLD,c%NDims,nsubs,c%Periodicity,c%Reorder,comm,iErr)
call MPI_Cart_get(comm,c%NDims,nsubs,c%Periodicity,subs,iErr)
c%Comm=comm
c%NSubDomains=nsubs
c%SubDomainCoords=subs
end subroutine
end module
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: fortran 90 passing user defined type member to a c fucntion
2010-03-26 22:02 fortran 90 passing user defined type member to a c fucntion burlen
@ 2010-03-27 6:28 ` Ian Lance Taylor
2010-03-28 3:12 ` burlen
0 siblings, 1 reply; 6+ messages in thread
From: Ian Lance Taylor @ 2010-03-27 6:28 UTC (permalink / raw)
To: burlen; +Cc: gcc-help
burlen <burlen.loring@gmail.com> writes:
> When calling a c function from a fortran 90 program with members of a
> user defined types for output arguments of the called subroutine the
> user defined types aren't being modified as they should be (according
> to my understanding).
When you call a C function, you get the C rules. It doesn't matter
whether you are calling it from Fortran or not. In C, a modification
of an argument is not reflected back to the caller.
Ian
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: fortran 90 passing user defined type member to a c fucntion
2010-03-27 6:28 ` Ian Lance Taylor
@ 2010-03-28 3:12 ` burlen
2010-03-28 7:29 ` Ian Lance Taylor
2010-03-28 20:52 ` Tim Prince
0 siblings, 2 replies; 6+ messages in thread
From: burlen @ 2010-03-28 3:12 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: gcc-help
Ian Lance Taylor wrote:
> burlen <burlen.loring@gmail.com> writes:
>
>
>> When calling a c function from a fortran 90 program with members of a
>> user defined types for output arguments of the called subroutine the
>> user defined types aren't being modified as they should be (according
>> to my understanding).
>>
>
> When you call a C function, you get the C rules. It doesn't matter
> whether you are calling it from Fortran or not. In C, a modification
> of an argument is not reflected back to the caller.
>
> Ian
>
In my understanding, Fortran unless otherwise instructed is supposed to
pass by address. In the c function modifying the data pointed to should
do just that, and be visible to the caller. What I don't understand is
why passing the member of a user defined type behaves as if it's passed
by value in this case, while passing the corresponding native type is
passed by address and works as expected.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: fortran 90 passing user defined type member to a c fucntion
2010-03-28 3:12 ` burlen
@ 2010-03-28 7:29 ` Ian Lance Taylor
2010-03-28 20:22 ` burlen
2010-03-28 20:52 ` Tim Prince
1 sibling, 1 reply; 6+ messages in thread
From: Ian Lance Taylor @ 2010-03-28 7:29 UTC (permalink / raw)
To: burlen; +Cc: gcc-help
burlen <burlen.loring@gmail.com> writes:
> Ian Lance Taylor wrote:
>> burlen <burlen.loring@gmail.com> writes:
>>
>>
>>> When calling a c function from a fortran 90 program with members of a
>>> user defined types for output arguments of the called subroutine the
>>> user defined types aren't being modified as they should be (according
>>> to my understanding).
>>>
>>
>> When you call a C function, you get the C rules. It doesn't matter
>> whether you are calling it from Fortran or not. In C, a modification
>> of an argument is not reflected back to the caller.
>>
>> Ian
>>
> In my understanding, Fortran unless otherwise instructed is supposed
> to pass by address. In the c function modifying the data pointed to
> should do just that, and be visible to the caller. What I don't
> understand is why passing the member of a user defined type behaves as
> if it's passed by value in this case, while passing the corresponding
> native type is passed by address and works as expected.
I think you are going to have to provide an example.
If you write a C function
void foo(int i) { i = 1; }
then the parameter is not going to change in the caller. That's just
how C works. There is no reasonable way to change that.
Ian
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: fortran 90 passing user defined type member to a c fucntion
2010-03-28 7:29 ` Ian Lance Taylor
@ 2010-03-28 20:22 ` burlen
0 siblings, 0 replies; 6+ messages in thread
From: burlen @ 2010-03-28 20:22 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: gcc-help
Ian Lance Taylor wrote:
> burlen <burlen.loring@gmail.com> writes:
>
>
>> Ian Lance Taylor wrote:
>>
>>> burlen <burlen.loring@gmail.com> writes:
>>>
>>>
>>>
>>>> When calling a c function from a fortran 90 program with members of a
>>>> user defined types for output arguments of the called subroutine the
>>>> user defined types aren't being modified as they should be (according
>>>> to my understanding).
>>>>
>>>>
>>> When you call a C function, you get the C rules. It doesn't matter
>>> whether you are calling it from Fortran or not. In C, a modification
>>> of an argument is not reflected back to the caller.
>>>
>>> Ian
>>>
>>>
>> In my understanding, Fortran unless otherwise instructed is supposed
>> to pass by address. In the c function modifying the data pointed to
>> should do just that, and be visible to the caller. What I don't
>> understand is why passing the member of a user defined type behaves as
>> if it's passed by value in this case, while passing the corresponding
>> native type is passed by address and works as expected.
>>
>
>
> I think you are going to have to provide an example.
>
>
> If you write a C function
>
> void foo(int i) { i = 1; }
>
> then the parameter is not going to change in the caller. That's just
> how C works. There is no reasonable way to change that.
>
> Ian
>
True. But when you're mixing fortran and c you don't write your c
function that way, because fortran passes by address. I don't know if
it's mandated by a standard or not, but that's just how it's implemented
in my experience. I have used mixed language programming with gnu,
intel, and portland group. This is my first attempt at making use of the
so called object oriented features of fortran 90 .
For example your function would have to be written as follows:
/* start of c code */
void foo_(int *i)
{
(*i)=1;
}
/* end of c code */
This can be called from a fortran program as follows:
! start of fortran code
program main
integer i
i=0
call foo(i)
write(0,*)i
end program
! end of fortran code
compile like this:
$ gcc ccode.c -c -o ccode.o
$ gfortran fcode.f90 ccode.o -o fcode
$ ./fcode
1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: fortran 90 passing user defined type member to a c fucntion
2010-03-28 3:12 ` burlen
2010-03-28 7:29 ` Ian Lance Taylor
@ 2010-03-28 20:52 ` Tim Prince
1 sibling, 0 replies; 6+ messages in thread
From: Tim Prince @ 2010-03-28 20:52 UTC (permalink / raw)
To: gcc-help
On 3/27/2010 10:40 AM, burlen wrote:
> Ian Lance Taylor wrote:
>> burlen <burlen.loring@gmail.com> writes:
>>
>>> When calling a c function from a fortran 90 program with members of a
>>> user defined types for output arguments of the called subroutine the
>>> user defined types aren't being modified as they should be (according
>>> to my understanding).
>>
>> When you call a C function, you get the C rules. It doesn't matter
>> whether you are calling it from Fortran or not. In C, a modification
>> of an argument is not reflected back to the caller.
>>
>> Ian
> In my understanding, Fortran unless otherwise instructed is supposed
> to pass by address. In the c function modifying the data pointed to
> should do just that, and be visible to the caller. What I don't
> understand is why passing the member of a user defined type behaves as
> if it's passed by value in this case, while passing the corresponding
> native type is passed by address and works as expected.
>
If you wish to assure control over pass by value/reference, it's all
there in iso_c_binding. You appear to be trying to avoid standard
facilities on the Fortran, and you're leaving us guessing about your C side.
--
Tim Prince
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-03-28 3:04 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-26 22:02 fortran 90 passing user defined type member to a c fucntion burlen
2010-03-27 6:28 ` Ian Lance Taylor
2010-03-28 3:12 ` burlen
2010-03-28 7:29 ` Ian Lance Taylor
2010-03-28 20:22 ` burlen
2010-03-28 20:52 ` Tim Prince
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).