|
|
 |
 |
 |
 |
Fortran Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
linking C functions...
On May 23, 1:23 am, fred <fredantis@free.fr> wrote:
> Hi, > I get the following strange behavior, linking a C function > in my fortran code. The result is obviously wrong: > [pts/0]:~/tmp/{4}/> ./call_func_f > funcs( 0, 2.) = 0. > funcs( 1, 2.) = 0. > where call_func_f.f is: > program essai > implicit none > real :: funcs > integer :: i > real :: x > x = 2 > do i = 0,1 > print *, 'funcs(', i, ',', x, ') = ', funcs(i, x) > end do > end program > c Local Variables: > c mode: Fortran > c compile-command: "g77 -Wall call_func.f funcs.o -o call_func_f" > c End: > and funcs.c is: > #include <math.h> > float foo(float x) > { > return(x*x); > } > float bar(float x) > { > return(x*x*x); > } > float funcs_(int *i, float *x) > { > float (*pfunc[])(float) = {foo, bar}; > return((*pfunc[*i])(*x)); > } > /* Local Variables: */ > /* mode: C */ > /* compile-command: "gcc -Wall -fPIC funcs.c -c -o funcs.o" */ > /* End: */ > Notes: there is no such issue under i686 arch > Any suggestions are welcome. > Thanks in advance. > Cheers, > PS: debian etch, gcc 4.1.1, g77 3.4.6 > -- > Fred.
Try printing the values of x in foo and bar. Bob Corbett
On May 23, 1:23 am, fred <fredantis@free.fr> wrote:
> Hi, > I get the following strange behavior, linking a C function > in my fortran code. The result is obviously wrong: > [pts/0]:~/tmp/{4}/> ./call_func_f > funcs( 0, 2.) = 0. > funcs( 1, 2.) = 0. > where call_func_f.f is: > program essai > implicit none > real :: funcs > integer :: i > real :: x > x = 2 > do i = 0,1 > print *, 'funcs(', i, ',', x, ') = ', funcs(i, x) > end do > end program > c Local Variables: > c mode: Fortran > c compile-command: "g77 -Wall call_func.f funcs.o -o call_func_f" > c End: > and funcs.c is: > #include <math.h> > float foo(float x) > { > return(x*x); > } > float bar(float x) > { > return(x*x*x); > } > float funcs_(int *i, float *x) > { > float (*pfunc[])(float) = {foo, bar}; > return((*pfunc[*i])(*x)); > } > /* Local Variables: */ > /* mode: C */ > /* compile-command: "gcc -Wall -fPIC funcs.c -c -o funcs.o" */ > /* End: */ > Notes: there is no such issue under i686 arch > Any suggestions are welcome. > Thanks in advance. > Cheers, > PS: debian etch, gcc 4.1.1, g77 3.4.6 > -- > Fred.
Try printing the values of x in foo and bar. Bob Corbett
On 23 mei, 10:23, fred <fredantis@free.fr> wrote:
> Hi, > I get the following strange behavior, linking a C function > in my fortran code. The result is obviously wrong: > [pts/0]:~/tmp/{4}/> ./call_func_f > funcs( 0, 2.) = 0. > funcs( 1, 2.) = 0. > where call_func_f.f is: > program essai > implicit none > real :: funcs > integer :: i > real :: x > x = 2 > do i = 0,1 > print *, 'funcs(', i, ',', x, ') = ', funcs(i, x) > end do > end program > c Local Variables: > c mode: Fortran > c compile-command: "g77 -Wall call_func.f funcs.o -o call_func_f" > c End: > and funcs.c is: > #include <math.h> > float foo(float x) > { > return(x*x); > } > float bar(float x) > { > return(x*x*x); > } > float funcs_(int *i, float *x) > { > float (*pfunc[])(float) = {foo, bar}; > return((*pfunc[*i])(*x)); > } > /* Local Variables: */ > /* mode: C */ > /* compile-command: "gcc -Wall -fPIC funcs.c -c -o funcs.o" */ > /* End: */ > Notes: there is no such issue under i686 arch > Any suggestions are welcome. > Thanks in advance. > Cheers, > PS: debian etch, gcc 4.1.1, g77 3.4.6 > -- > Fred.
Hm, what happens if you declare funcs to be external? (Frankly, I am surprised it compiles at all: funcs is declared a scalar variable, but it is used as an array with odd indices - i.e. one index is real: or should this trigger the compiler into realising it is a function, not an array?) Regards, Arjen
On 23 mei, 10:23, fred <fredantis@free.fr> wrote:
> Hi, > I get the following strange behavior, linking a C function > in my fortran code. The result is obviously wrong: > [pts/0]:~/tmp/{4}/> ./call_func_f > funcs( 0, 2.) = 0. > funcs( 1, 2.) = 0. > where call_func_f.f is: > program essai > implicit none > real :: funcs > integer :: i > real :: x > x = 2 > do i = 0,1 > print *, 'funcs(', i, ',', x, ') = ', funcs(i, x) > end do > end program > c Local Variables: > c mode: Fortran > c compile-command: "g77 -Wall call_func.f funcs.o -o call_func_f" > c End: > and funcs.c is: > #include <math.h> > float foo(float x) > { > return(x*x); > } > float bar(float x) > { > return(x*x*x); > } > float funcs_(int *i, float *x) > { > float (*pfunc[])(float) = {foo, bar}; > return((*pfunc[*i])(*x)); > } > /* Local Variables: */ > /* mode: C */ > /* compile-command: "gcc -Wall -fPIC funcs.c -c -o funcs.o" */ > /* End: */ > Notes: there is no such issue under i686 arch > Any suggestions are welcome. > Thanks in advance. > Cheers, > PS: debian etch, gcc 4.1.1, g77 3.4.6 > -- > Fred.
Hm, what happens if you declare funcs to be external? (Frankly, I am surprised it compiles at all: funcs is declared a scalar variable, but it is used as an array with odd indices - i.e. one index is real: or should this trigger the compiler into realising it is a function, not an array?) Regards, Arjen
On 23 mei, 10:23, fred <fredantis@free.fr> wrote:
> Hi, > I get the following strange behavior, linking a C function > in my fortran code. The result is obviously wrong: > [pts/0]:~/tmp/{4}/> ./call_func_f > funcs( 0, 2.) = 0. > funcs( 1, 2.) = 0. > where call_func_f.f is: > program essai > implicit none > real :: funcs > integer :: i > real :: x > x = 2 > do i = 0,1 > print *, 'funcs(', i, ',', x, ') = ', funcs(i, x) > end do > end program > c Local Variables: > c mode: Fortran > c compile-command: "g77 -Wall call_func.f funcs.o -o call_func_f" > c End: > and funcs.c is: > #include <math.h> > float foo(float x) > { > return(x*x); > } > float bar(float x) > { > return(x*x*x); > } > float funcs_(int *i, float *x) > { > float (*pfunc[])(float) = {foo, bar}; > return((*pfunc[*i])(*x)); > } > /* Local Variables: */ > /* mode: C */ > /* compile-command: "gcc -Wall -fPIC funcs.c -c -o funcs.o" */ > /* End: */ > Notes: there is no such issue under i686 arch > Any suggestions are welcome. > Thanks in advance. > Cheers, > PS: debian etch, gcc 4.1.1, g77 3.4.6 > -- > Fred.
Hm, what happens if you declare funcs to be external? (Frankly, I am surprised it compiles at all: funcs is declared a scalar variable, but it is used as an array with odd indices - i.e. one index is real: or should this trigger the compiler into realising it is a function, not an array?) Regards, Arjen
On 23 mei, 10:23, fred <fredantis@free.fr> wrote:
> Hi, > I get the following strange behavior, linking a C function > in my fortran code. The result is obviously wrong: > [pts/0]:~/tmp/{4}/> ./call_func_f > funcs( 0, 2.) = 0. > funcs( 1, 2.) = 0. > where call_func_f.f is: > program essai > implicit none > real :: funcs > integer :: i > real :: x > x = 2 > do i = 0,1 > print *, 'funcs(', i, ',', x, ') = ', funcs(i, x) > end do > end program > c Local Variables: > c mode: Fortran > c compile-command: "g77 -Wall call_func.f funcs.o -o call_func_f" > c End: > and funcs.c is: > #include <math.h> > float foo(float x) > { > return(x*x); > } > float bar(float x) > { > return(x*x*x); > } > float funcs_(int *i, float *x) > { > float (*pfunc[])(float) = {foo, bar}; > return((*pfunc[*i])(*x)); > } > /* Local Variables: */ > /* mode: C */ > /* compile-command: "gcc -Wall -fPIC funcs.c -c -o funcs.o" */ > /* End: */ > Notes: there is no such issue under i686 arch > Any suggestions are welcome. > Thanks in advance. > Cheers, > PS: debian etch, gcc 4.1.1, g77 3.4.6 > -- > Fred.
Hm, what happens if you declare funcs to be external? (Frankly, I am surprised it compiles at all: funcs is declared a scalar variable, but it is used as an array with odd indices - i.e. one index is real: or should this trigger the compiler into realising it is a function, not an array?) Regards, Arjen
Arjen Markus wrote: > Hm, what happens if you declare funcs to be external? > (Frankly, I am surprised it compiles at all: funcs is > declared a scalar variable, but it is used as an array with > odd indices - i.e. one index is real: or should this trigger > the compiler into realising it is a function, not an array?)
Yes it should (and does). What happens if you call funcs and print separately, i.e. z = funcs(i,x) print *, 'funcs(', i, ',', x, ') = ', z
fred wrote: > I get the following strange behavior, linking a C function > in my fortran code. The result is obviously wrong: > [pts/0]:~/tmp/{4}/> ./call_func_f > funcs( 0, 2.) = 0. > funcs( 1, 2.) = 0.
It works using gcc and gfortran. It might be that g77 has a different calling sequence than gcc. -- glen
On May 23, 3:55 am, fred <fredantis@free.fr> wrote: > robert.corb @sun.com a crit : > > Try printing the values of x in foo and bar. > And then ? > I can print them. > What's the problem ?
What are the values? Are they zero? Bob Corbett
On May 23, 3:55 am, fred <fredantis@free.fr> wrote: > robert.corb @sun.com a crit : > > Try printing the values of x in foo and bar. > And then ? > I can print them. > What's the problem ?
Basically, I see two possible explanations for what you are seeing. One is that the way the arguments are being passed is mismatched. The other is that the way the values are returned is mismatched. Given that g77 and the version of gcc you are using are of different generations, either explanation is possible. If the values of x in foo and bar are correct, the problem must be with the return. Bob Corbett Bob Corbett
On May 23, 1:23 am, fred <fredantis@free.fr> wrote: > Notes: there is no such issue under i686 arch
Which architecture are you compiling for? Bob Corbett
On 23 mei, 13:01, fred <fredantis@free.fr> wrote:
> Arjen Markus <arjen.mar @wldelft.nl> a crit : > > Hm, what happens if you declare funcs to be external? > How can I do that ? > > (Frankly, I am surprised it compiles at all: funcs is > > declared a scalar variable, but it is used as an array with > > odd indices - i.e. one index is real: or should this trigger > > the compiler into realising it is a function, not an array?) > I see nothing strange in my code. > I don't see any index which ise real. > Where do you see this? > --http://scipy.org/FredericPetit
"funcs" is declared to be of real type, but it is not evident from the declaration that it is an external function. I thought that the use you make of it (funcs(i,x), with x the real argument) could make the compiler think you are abusing funcs. My mistake - it has been some years since I used that style (mostly by mistake). Nowadays I try to make sure everything has an explicit interface or is imported from a module. Regards, Arjen
On May 23, 4:18 am, robert.corb@sun.com wrote: > On May 23, 1:23 am, fred <fredantis @free.fr> wrote: > > Notes: there is no such issue under i686 arch > Which architecture are you compiling for?
Bad question. I should have checked the topic line. Bob Corbett
fred wrote: > Yes, I know that. > But I want to understand what happens, or if I made > a mistake somewhere... ;-)
If you want to understand what happens, compile with -S and you should see what the mismatch is (since we know now that it should be on returning the function value). As for mistakes, the only one is to assume that a change of compiler/target architecture is not going to have some potential effects on mixed language programming. Mixed programming is very sensitive: any change might break something. That's life !
robert.corb @sun.com wrote: (snip) > Basically, I see two possible explanations for what > you are seeing. One is that the way the arguments > are being passed is mismatched. The other is that > the way the values are returned is mismatched. Given > that g77 and the version of gcc you are using are of > different generations, either explanation is possible. > If the values of x in foo and bar are correct, the > problem must be with the return.
I have gfortran and gcc on an x86_64 machine and it works. (And that was before I noticed that the OP asked for x86_64.) The generated code for funcs_() in my case is: funcs_: .LFB4: pushq %rbp .LCFI4: movq %rsp, %rbp .LCFI5: subq $48, %rsp .LCFI6: movq %rdi, -24(%rbp) movq %rsi, -32(%rbp) movq $foo, -16(%rbp) movq $bar, -8(%rbp) movq -24(%rbp), %rax movl (%rax), %eax cltq movq -16(%rbp,%rax,8), %rdx movq -32(%rbp), %rax movss (%rax), %xmm0 call *%rdx movss %xmm0, -36(%rbp) movl -36(%rbp), %eax movl %eax, -36(%rbp) movss -36(%rbp), %xmm0 leave ret Which looks like the return is in %xmm0. Interesting that it moves the result from %xmm0 to -36(%rbp) to eax to -36(%rbp) to %xmm0. -- glen
|
 |
 |
 |
 |
|