------- Comment #4 from burnus at gcc dot gnu dot org  2008-07-23 09:25 -------
First of all: If you want to see in C-like syntax which interface gfortran
generates, compile "gfortran -fdump-tree-original -c myopenbf.f", which
generates a myopenbf.f.003t.original file.


Secondly:
   myopenbf_(bfin,&ibuf,2);

Here, you tell the Fortran compiler that the string is 2 characters long; thus
  IO='OUT'
does the C equivalent of IO[0]='O'; IO[1]='U'. Thus you can never assign 4
characters and also no '\0' will be appended.

Fortran always needs for characters the length as trailing argument thus you
CANNOT simply use:
  myopenbf_(bfin,&ibuf);


Actually, this is not much different form C, except that it is made easier in C
overwrite the bounds. If you use  snprintf() you also need to pass the
maximally allowed length. (For sprintf you don't but you might get buffer
overruns.)  Since Fortran does not add a trailing '\0' one needs to take extra
care.


If you do not want to pass the character length, you need to use BIND(C)
feature of the Fortran 2003 standard, which allows this.


Thirdly, I do not see any difference in using "character(*)" vs.
"character*(*)". Nor do I see any difference between using the Intel or the GNU
Fortran compiler.


And the following Program works with g++ 4.3 and ifort / gfortran 4.4.0:

using namespace std;
#include <iostream>
extern "C" {
  void myopenbf_( char *, int *, int);
}
int main(int argc, char *argv[])
{
  int ibuf = 2;
  char bfin[4];
  bfin[0]='I'; bfin[1]='N'; bfin[2]='\0'; bfin[3]='\0';
  cout << bfin << "\n" << flush;
  myopenbf_(bfin, &ibuf, sizeof(bfin));
  cout << bfin << "\n" << flush;
}


      SUBROUTINE MYOPENBF(IO,LUNDX)
        INTEGER LUNDX
        CHARACTER*(*) IO
        print *, 'LUNDX=',LUNDX
        print *, 'IO=',IO
        ! char length: 2->'OU', 4-> 'OUT\0'
        IO='OUT'//achar(0)
        print *, 'IO=',IO
      END

I would pass  sizeof(bfin)  as last argument. If you want to print the string
in Fortran (and not just assign to it), you need a stringlength function, e.g.

integer function strlen(str)
  character(len=*) :: str
  integer :: i
  strlen = 0
  do
    if(str(strlen:strlen) == achar(0)) exit
    strlen = strlen + 1
  end do
end function strlen

Then you can do:

  print *, mystr(1:strlen(mystr))

in Fortran.

Thus: I believe the bug is rightly closed as INVALID.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36894

Reply via email to