2

I am working on a project where I have to use a Fortran library in C. In the Fortran library there is a common block containing a complex*16, 4x4 array. Now in C, a complex variable is simply a struct containing two elements and since it is complex*16, the elements should be long double, which is the corresponding C data type in Fortran. So I have a struct with two long doubles.

I am to access the elements of this array. Good thing is, I can already do that along with all other common variables of the library. The problem is that elements that I import from the array are,

1) Not in the order as the should be, "even after taking into account the difference in the array structure of C and Fotran".

2) While most elements are right, two are very different from what they should be.

3) I get the right elements (except for the two) only if I use double instead of long double. When I use long double (and the correct character conversions) I get something entirely different which clearly points to a problem with conversions.

I have exhausted every explaination I had but nothing works. My code for priting arrays in C is the following:

for (j=0;j<=3;j++){
    printf("%s", "\n");
    for(k=0;k<=3;k++){            
        printf("%s %d %s %d %s %s %LE %s %LE %s",
          "(", k+1, "," ,j+1, ")", "{",
          (long double)mssmmixing_.neunmx[k][j].dr,
          " ",
          (long double)mssmmixing_.neunmx[k][j].di,
          "}\n");           
    }
}

Additional Info: Since I have to mix Fortran Object files, I am using gfortran to compile the C files. If I use GNU C compiler instead, it throws errors about not recognizing gfortran routines. This might also be a source of problem, may be the gfortran does not recognize long doubles in C.

Any help will be useful.

AstroCB
  • 12,337
  • 20
  • 57
  • 73
Shaz
  • 273
  • 2
  • 6
  • 12
  • I'm not sure about `long double`. In my (limited) experience the C `double` corresponds to Fortran's `real*8`. And `complex*16` is essentially a pair of `real*8`-s. Did you try making a toy Fortran code with a common block of only `real*8`-s? – ev-br Oct 31 '11 at 21:05
  • Yes, I did. The algo I am using works for that case. But not in my case. – Shaz Nov 01 '11 at 10:38
  • well then, does it get any better if you only use `double`, not `long double`? And, er, there are no off-by-one errors by any chance? --- Fortran codes often use 1-based arrays instead of 0-based. – ev-br Nov 01 '11 at 13:07

1 Answers1

2

For mixing Fortran and C, I recommend the use of the ISO_C_Binding. It even has a Fortran type C_LONG_DOUBLE_COMPLEX that matches the C type long double _Complex -- see http://gcc.gnu.org/onlinedocs/gfortran/ISO_005fC_005fBINDING.html. As part of the Fortran language standard these types are guaranteed to match (when you use compatible compilers). Very likely C_LONG_DOUBLE_COMPLEX is actually the same as complex*16 but you could try, in Fortran, copying between the two types in case the memory layout is different. You should compile the Fortran source files with gfortran and the C with gcc. It is easiest to link with gfortran. (Or use other "brand" compilers.)

M. S. B.
  • 28,968
  • 2
  • 46
  • 73
  • Thanks. I am new to Fortran. Can you guide me a little on how to use this module. – Shaz Oct 31 '11 at 14:49
  • "Since I have to mix Fortran Object files, I am using gfortran to compile the C files." I do not really understand, can you specify it? – Vladimir F Героям слава Nov 01 '11 at 08:55
  • Meaning that when I compile my C code it has to include some object files compiled in GFortran. If I do not use GFortran compiler, I get errors because the CC compiler does not recognize the GFortran procedures. – Shaz Nov 01 '11 at 10:45