where is the mistake ?

This is a discussion on where is the mistake ? within the Fortran forums in Programming Languages category; I try to use a C function returning a single character : char cdir(void){return '/';} Here is the test program (test.f90) MODULE mod INTERFACE FUNCTION cdir() BIND(C,name="cdir") RESULT(r) USE iso_c_binding CHARACTER(kind=C_CHAR) :: r END FUNCTION END INTERFACE END MODULE PROGRAM test USE mod WRITE(*,*) cdir() WRITE(*,*) ICHAR(cdir()) END PROGRAM Expected result : / 47 The results with 3 different compilers : g95 test.f90 cdir.o ../a.out 0 ifort test.f90 cdir.o ../a.out 63 gfortran test.f90 cdir.o => internal compiler error Versions used : g95 : gcc version 4.0.3 (g95 0.92!) Aug 21 2008 ifort :10.0 gfortran : 4.4.0 20080821 If I replace ...

Go Back   Application Development Forum > Programming Languages > Fortran

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 08-22-2008, 10:21 AM
fj
Guest
 
Default where is the mistake ?

I try to use a C function returning a single character :

char cdir(void){return '/';}

Here is the test program (test.f90)

MODULE mod
INTERFACE
FUNCTION cdir() BIND(C,name="cdir") RESULT(r)
USE iso_c_binding
CHARACTER(kind=C_CHAR) :: r
END FUNCTION
END INTERFACE
END MODULE

PROGRAM test
USE mod
WRITE(*,*) cdir()
WRITE(*,*) ICHAR(cdir())
END PROGRAM

Expected result :
/
47

The results with 3 different compilers :

g95 test.f90 cdir.o
../a.out

0

ifort test.f90 cdir.o
../a.out

63

gfortran test.f90 cdir.o
=> internal compiler error

Versions used :

g95 : gcc version 4.0.3 (g95 0.92!) Aug 21 2008
ifort :10.0
gfortran : 4.4.0 20080821

If I replace the function "cdir" by the procedure "getdir" , then all
is OK :

void getdir(char *c){*c='/';}

MODULE mod
INTERFACE
SUBROUTINE getdir(c) BIND(C,name="getdir")
USE iso_c_binding
CHARACTER(kind=C_CHAR) :: c
END SUBROUTINE
END INTERFACE
END MODULE

PROGRAM test
USE mod
CHARACTER :: c
CALL getdir(c)
WRITE(*,*) c
WRITE(*,*) ICHAR(c)
END PROGRAM

Results with the three compilers :
/
47
Reply With Quote
  #2  
Old 08-22-2008, 10:28 AM
Arjen Markus
Guest
 
Default Re: where is the mistake ?

On 22 aug, 16:21, fj <francois.j...@irsn.fr> wrote:
> I try to use a C function returning a single character :
>
> char cdir(void){return '/';}
>
> Here is the test program (test.f90)
>
> MODULE mod
> * INTERFACE
> * * FUNCTION cdir() BIND(C,name="cdir") RESULT(r)
> * * * USE iso_c_binding
> * * * CHARACTER(kind=C_CHAR) :: r
> * * END FUNCTION
> * END INTERFACE
> END MODULE
>
> PROGRAM test
> * USE mod
> * WRITE(*,*) cdir()
> * WRITE(*,*) ICHAR(cdir())
> END PROGRAM
>
> Expected result :
> */
> *47
>
> The results with 3 different compilers :
>
> g95 test.f90 cdir.o
> ./a.out
>
> 0
>
> ifort test.f90 cdir.o
> ./a.out
>
> 63
>
> gfortran test.f90 cdir.o
> => internal compiler error
>
> Versions used :
>
> g95 : gcc version 4.0.3 (g95 0.92!) Aug 21 2008
> ifort :10.0
> gfortran : 4.4.0 20080821
>
> If I replace the function "cdir" by the procedure "getdir" , then all
> is OK :
>
> void getdir(char *c){*c='/';}
>
> MODULE mod
> * INTERFACE
> * * SUBROUTINE getdir(c) BIND(C,name="getdir")
> * * * USE iso_c_binding
> * * * CHARACTER(kind=C_CHAR) :: c
> * * END SUBROUTINE
> * END INTERFACE
> END MODULE
>
> PROGRAM test
> * USE mod
> * CHARACTER :: c
> * CALL getdir(c)
> * WRITE(*,*) c
> * WRITE(*,*) ICHAR(c)
> END PROGRAM
>
> Results with the three compilers :
> /
> 47


Hm, C is a bit funny when it comes to characters. They
are almost but not entirely integers. Perhaps you ought
to try:
INTEGER :: r

(And I can imagine the compilers focus on strings, rather
individual characters ...)

Regards,

Arjen
Reply With Quote
  #3  
Old 08-22-2008, 01:47 PM
Richard Maine
Guest
 
Default Re: where is the mistake ?

Arjen Markus <arjen.markus@wldelft.nl> wrote:

> On 22 aug, 16:21, fj <francois.j...@irsn.fr> wrote:
> > I try to use a C function returning a single character :


> Hm, C is a bit funny when it comes to characters. They
> are almost but not entirely integers. Perhaps you ought
> to try:
> INTEGER :: r


No, that doesn't seem right. regardless of C's "funniness" with char
type, the f2003 standard defines C char to interoperate with Fortran
character(kind=c_char), as the OP does it. Perhaps one might be able to
do a workaround along those lines, but that isn't the "right" solution
for the f2003 C interop stuff. My suspicions would lie elsewhere.

1. Your function returns char instead of *char. I suppose that's
probably ok and perhaps even the right thing to do, but it seems
strange. I haven't worked through the implications, but something seems
awry here in that I don't see how the same interface could correctly
describe both a function returning char and another one returning *char.
Heck, that's back to one of the eternal problems with writing and
interfacing with C code - getting off by one in the level of pointer
indirection.

2. Character is so much a special case, and functions returning
character even more so, that it wouldn't shock me for compilers not to
have gotten that right yet. But all 3 compilers getting it wrong would
seem to greatly lower the odds of that.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
Reply With Quote
  #4  
Old 08-22-2008, 05:30 PM
Tobias Burnus
Guest
 
Default Re: where is the mistake ?

On 22 Aug., 19:47, nos...@see.signature (Richard Maine) wrote:
> Arjen Markus <arjen.mar...@wldelft.nl> wrote:
> > They
> > are almost but not entirely integers. Perhaps you ought
> > to try:
> > INTEGER :: r


I think that should work - with INTEGER(C_SIGNED_CHAR). However,
before you can print the result, you need to transfer the
INTEGER(C_SIGNED_CHAR) to character.

Otherwise I believe the program is valid - and NAG f95 also works with
it.


> 1. Your function returns char instead of *char. I suppose that's
> probably ok and perhaps even the right thing to do, but it seems
> strange.


Why? integer(c_int) also returns an int and not an int*. (Remember
that only length-1 characters are allowed with bind(C).)

> I haven't worked through the implications, but something seems
> awry here in that I don't see how the same interface could correctly
> describe both a function returning char and another one returning *char.


That's simple: for char* you need a pointer, i.e. type(c_ptr). The
extra indirection only comes into play for the arguments due to
Fortran's call by reference.

Tobias
Reply With Quote
  #5  
Old 08-22-2008, 05:46 PM
glen herrmannsfeldt
Guest
 
Default Re: where is the mistake ?

Arjen Markus wrote:
(snip)

> Hm, C is a bit funny when it comes to characters. They
> are almost but not entirely integers. Perhaps you ought
> to try:
> INTEGER :: r


> (And I can imagine the compilers focus on strings, rather
> individual characters ...)


C character constants are integers. (try sizeof('/'))

char and short function arguments are normally converted
to int before function calls. That may also tend to
happen with function return values. A proper C
interoperability implementation will know about the
return convention, but it might take a while to
get there.

Yes, I wouldn't be surprised if a C function of
type char returned an int.

-- glen

Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 02:52 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.