Calling a FORTRAN function that returns a complex

  • Thread starter Klaas Vantournhout
  • Start date
K

Klaas Vantournhout

Hi all,

I was wondering why there is one extra argument for the return values of
complex functions. And why is this not the case with any other data
type (except char)

example :

* In case of a non complex value

=== FORTRAN ===
real function f(p)
real p
f = p
return
end
=== C-call / C++-call ===
extern float f_(float *); // for C
// extern "C" { float f_(float *); } // for C++
float r,s;
s = f_(&r);
==============

* in case of a complex value
=== FORTRAN ===
complex function f(p)
complex p
f = p
return
end
=== C-call ===
typedef struct { float r,i; } complex
extern void f_(complex *return, complex *);

complex r,s;
f_(&s,&r);
====C++ call=====
extern "C" { void f_(std::complex<float> *return, std::complex<float> *);

std::complex<float> r,s;
f_(&s,&r);
===================

So what is the structural reason of this difference
float f_(float *);
void f_(complex *return, complex *);


Hoping on an answer,
With kind regards
Klaas
 
J

Jim Langston

Klaas Vantournhout said:
Hi all,

I was wondering why there is one extra argument for the return values of
complex functions. And why is this not the case with any other data
type (except char)

example :

* In case of a non complex value

=== FORTRAN ===
real function f(p)
real p
f = p
return
end
=== C-call / C++-call ===
extern float f_(float *); // for C
// extern "C" { float f_(float *); } // for C++
float r,s;
s = f_(&r);
==============

* in case of a complex value
=== FORTRAN ===
complex function f(p)
complex p
f = p
return
end
=== C-call ===
typedef struct { float r,i; } complex
extern void f_(complex *return, complex *);

complex r,s;
f_(&s,&r);
====C++ call=====
extern "C" { void f_(std::complex<float> *return, std::complex<float> *);

std::complex<float> r,s;
f_(&s,&r);
===================

So what is the structural reason of this difference
float f_(float *);
void f_(complex *return, complex *);

Look up the definitions of "real" and "imaginary" parts. That should give
you your answer.
 
S

SM Ryan

# Hi all,
#
# I was wondering why there is one extra argument for the return values of
# complex functions. And why is this not the case with any other data
# type (except char)

Between the caller values on the stack and callee values on the
stack, there is interleaved section for the function call/return
protocol. On return, the function results has to be moved over
linkage into the caller values. If the result value fits in the
registers, (such as integer or double precision), the result is
loaded there and the return executed with the caller able to
deposit the result where it wants.

If the results cannot fit in the registers due to size or brain
dead calling conventions, it typically has to be copied by the callee
to a preallocated slot in the caller; the address has to be passed
to the caller.
 
K

Klaas Vantournhout

Between the caller values on the stack and callee values on the
stack, there is interleaved section for the function call/return
protocol. On return, the function results has to be moved over
linkage into the caller values. If the result value fits in the
registers, (such as integer or double precision), the result is
loaded there and the return executed with the caller able to
deposit the result where it wants.

If the results cannot fit in the registers due to size or brain
dead calling conventions, it typically has to be copied by the callee
to a preallocated slot in the caller; the address has to be passed
to the caller.

Hmm, this clearly makes sense!
Thanks for the reply.

Klaas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top