I have a question that has been puzzling me for some time now. It regards the calling of a complex fortran function returning a complex value. (example cdotc ).
When you have a fortran compiled blas library, the general rule to call it is doing the following changes
- Code: Select all
real -> float
doublereal -> double
complex -> typedef struct { float r, i; } complex or just std::complex<float>
doublecomplex -> typedef struct { double r, i; } doublecomplex or just std::complex<double>
and everything becomes a pointer
if the fortran routine is a subroutine, the c translation becomes a function returning a void
if the fortran routine is a function returning a value, the c function returns the same translated type.
So this is all very nice and works fine
an example here is scopy which becomes then in c++
- Code: Select all
extern "C" {
void scopy_(long *, float *, long *, float *, long *);
}
or zcopy is then
- Code: Select all
extern "C" {
void zcopy_(long *, std::complex<double> *, long *, std::complex<double> *, long *);
}
Now this is nice, I have no problems with the above, but here is the thing that puzzles me. When addressing a fortran function (example sdot and cdotc) there apears a difference between returning a complex value or not. a real or doublereal has to be defined like this
- Code: Select all
extern "C" {
float sdot_(long *, float *, long *, float *, long *);
}
while a complex can not return a complex but must be defined as a void
- Code: Select all
extern "C" {
void cdotc_(std::complex<float> *result, long *, std::complex<float> *, long *, std::complex<float> *, long *);
}
What is the reason of this difference? Why cant I return a complex value, or even why can't i define a real function analogue to the complex one. The following two give sporadic seg faults, and never the correct result
- Code: Select all
extern "C" {
void sdot_(float *result, long *, float *, long *, float *, long *);
std::complex<float> cdotc_(long *, std::complex<float> *, long *, std::complex<float> *, long *);
}
Thanks
Klaas

