This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/36894] question on gfortran character*(*)
- From: "burnus at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 23 Jul 2008 09:25:01 -0000
- Subject: [Bug fortran/36894] question on gfortran character*(*)
- References: <bug-36894-16485@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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