This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
>> attached are two small test cases (Fortran & C), which try to open a >> bz2 file for reading (they require a, possibly empty, file 'test.bz2' >> in the same dir). The Fortran version uses ISO_C_BINDING interfaces >> for the calls to 'fopen' and 'BZ2_bzReadOpen', and both work as >> expected on Linux (x86_64): > > Yes, there is a bug with ISO_C_BINDING - but the bug is in your code ;-) Certainly possible. I admit that it took me quite a while to figure out a working interface on Linux. > At least the problem below is likely to cause problems on x86-64. I don't > know why you only see the problem on MacOS, it should also exist on 64bit > Linux. Well, I also tried running the test program with valgrind on Linux - but it did not show any errors there. Also these interfaces have proven to work with four different compilers: ifort, gfortran, g95, sunf95. > You declare: > >> interface >> function fOpen (path,mode) bind (c,NAME='fopen') >> use, intrinsic :: ISO_C_BINDING >> character(c_char) path(*),mode(*) >> integer(c_int) :: fOpen >> end function >> end interface > > However, POSIX defines that fopen returns a "FILE *". On most 32 bit > systems, it should work. However, on a 64bit system, it wont (or only by > chance). Either you should use a proper pointer like TYPE(c_ptr). Or, if you > want to use an integer, use: INTEGER(c_intptr_t). Well, ok, let's try it with TYPE(c_ptr) ... >> interface >> function bzReadOpen (bzerror,f,verbosity,small,unused,nUnused) bind >> (c,NAME='BZ2_bzReadOpen') >> use, intrinsic :: ISO_C_BINDING >> integer(c_int),value :: f,verbosity,small,nUnused >> integer(c_int) :: bzReadOpen,bzerror >> type(c_ptr) :: unused >> end function >> end interface > > This one looks bogus as well. bzerror and f are both pointers (int * and > FILE *). > > For bzerror: I think you really should use "INTEGER(c_int)" (w/o VALUE) - > that way you get a proper error return. This I'm doing already! > And for FILE *f: Here, you have to ensure that you pass all 64bits of the > result value of "fopen". Again, I would use a "TYPE(C_PTR),VALUE" which > reflects the black box best. But using an INTEGER(c_intptr_t),VALUE should > also work. (Cf. above for "fopen".) Ok, using TYPE(c_ptr) here, too. However, when the test case is updated accordingly (see attachment), I also end up with a valgrind error on Linux: #1 #2 ==19696== Invalid read of size 8 ==19696== at 0x5B17062: ferror (in /lib64/libc-2.17.so) ==19696== by 0x4E3F097: BZ2_bzReadOpen (in /usr/lib64/libbz2.so.1.0.6) ==19696== by 0x400B9F: MAIN__ (testBz2.f90:38) ==19696== by 0x400C3C: main (testBz2.f90:42) ==19696== Address 0x8 is not stack'd, malloc'd or (recently) free'd ==19696== Program received signal SIGSEGV: Segmentation fault - invalid memory reference. > But there are surely more problems. In particular: bzReadOpen reads much > more argument values from the stack than you put there. I'm not sure I understand what you mean ... Cheers, Janus
Attachment:
testBz2.f90
Description: Binary data
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |