Allocatable character variables in Fortran - fortran

My code (stripped down to what I think is relevant for this question) is
PROGRAM test
IMPLICIT NONE
CHARACTER(len=37) input
CHARACTER(len=:), allocatable :: input_trim
WRITE(*,*) 'Filename?'
READ(*,*) input
ALLOCATE(character(len=LEN(TRIM(input))) :: input_trim)
input_trim=trim(input)
.
.
.
END PROGRAM test
It works fine with Intel's Fortran compiler, however gfortran gives me a couple of errors, the first one being in the line saying
CHARACTER(len=:), allocatable :: input_trim
I'm not sure which compiler is 'right' regarding the Fortran standard. Plus I don't know how to achieve what I need in a different way?! I think what I'm doing is more of a workaround anyway. What I need is a character variable containing exactly the filename that was entered with no following spaces.
EDIT: The error is "Syntax error in CHARACTER declaration".
gfortran --version gives me "GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)"
EDIT 2: You're right regarding the allocate: With ifort, I don't need it. And gfortran crashes before that so maybe it doesn't need the allocate either but I cannot test this at the moment...

This
character (len=:), allocatable :: input_trim
is certainly syntactically correct in Fortran 2003. You don't say what the error that gfortran raises is, so I can't comment on why it doesn't accept the line -- perhaps you have an old version of the compiler installed.
With an up-to-date Fortran compiler (eg Intel Fortran v14.xxx) you don't need to allocate the character variable's size prior to assigning to it, you can simply write
input_trim = trim(input)
Note that
read(*,*) input_trim
won't work.

With Absoft Fortran, this compiles (haven't run with it yet):
character,dimension(:),allocatable::Line_for_IO !Metcalf,Reid,Cohen p. 107, w/mods
if(allocated(Line_for_IO)) deallocate(Line_for_IO)
allocate(Line_for_IO(7*n+40))

Related

Fortran allocate/reallocate character length to a character string length [duplicate]

My code (stripped down to what I think is relevant for this question) is
PROGRAM test
IMPLICIT NONE
CHARACTER(len=37) input
CHARACTER(len=:), allocatable :: input_trim
WRITE(*,*) 'Filename?'
READ(*,*) input
ALLOCATE(character(len=LEN(TRIM(input))) :: input_trim)
input_trim=trim(input)
.
.
.
END PROGRAM test
It works fine with Intel's Fortran compiler, however gfortran gives me a couple of errors, the first one being in the line saying
CHARACTER(len=:), allocatable :: input_trim
I'm not sure which compiler is 'right' regarding the Fortran standard. Plus I don't know how to achieve what I need in a different way?! I think what I'm doing is more of a workaround anyway. What I need is a character variable containing exactly the filename that was entered with no following spaces.
EDIT: The error is "Syntax error in CHARACTER declaration".
gfortran --version gives me "GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)"
EDIT 2: You're right regarding the allocate: With ifort, I don't need it. And gfortran crashes before that so maybe it doesn't need the allocate either but I cannot test this at the moment...
This
character (len=:), allocatable :: input_trim
is certainly syntactically correct in Fortran 2003. You don't say what the error that gfortran raises is, so I can't comment on why it doesn't accept the line -- perhaps you have an old version of the compiler installed.
With an up-to-date Fortran compiler (eg Intel Fortran v14.xxx) you don't need to allocate the character variable's size prior to assigning to it, you can simply write
input_trim = trim(input)
Note that
read(*,*) input_trim
won't work.
With Absoft Fortran, this compiles (haven't run with it yet):
character,dimension(:),allocatable::Line_for_IO !Metcalf,Reid,Cohen p. 107, w/mods
if(allocated(Line_for_IO)) deallocate(Line_for_IO)
allocate(Line_for_IO(7*n+40))

Automatic allocation failing when casting from integer to real(dp)

I don't know whether I'm hitting a compiler bug or missing something. I'm attempting to run the following code:
program test
implicit none
integer, parameter :: dp=kind(1.d0)
integer, allocatable :: int_mat(:,:)
integer, allocatable :: int_mat_2(:,:)
real(dp), allocatable :: real_mat(:,:)
allocate(int_mat(2,2))
int_mat = 0
int_mat_2 = int_mat
real_mat = int_mat ! Falls over here.
end program
Compiling and running with nagfor (flags: -f2003 -C=all) works as expected. Compiling and running with gfortran (flags: -std=f2003 -fcheck=all) fails at runtime with the error message:
At line 13 of file test.f90
Fortran runtime error: Array bound mismatch for dimension 1 of array 'real_mat' (1/2)
I would expect the code to succeed, as int_mat_2 and real_mat should be allocated implicitly. This seems to be happening correctly for int_mat_2 but not for real_mat.
I have tried this with various gfortran versions (5.4, 6.3, 7.0), and all have the same problem.
As found by francescalus, this was this compiler bug, which has since been fixed for more recent gfortran versions.

Intel Visual Fortran allocatable array of fixed length strings

Running Intel Parallel Studio 2015 and Visual Studio 2012. Fortran 2003 compatibility turned on.
Is there an issue with the following code because it caused a very confusing (for me at least) heap corruption error on my machine and I'm trying to find out if it is something I'm not understanding correctly or a compiler bug.
character(len=200), dimension(:), allocatable :: inFNs
real*8, dimension(:), allocatable :: times
inFNs = (/ "file1.dat", "file2.dat", &
"file3.dat", "file4.dat", &
"file5.dat", "file6.dat" /)
allocate(times(SIZE(inFNs))
!more code below
The code would crash without a stack trace during the allocation of times, and it would tell me that a heap corruption occurred in a window dialog in debug mode.
The way I determined there was an issue with inFNs was because the issue would occur during a later allocate call if I moved the times allocation to be above inFNs.
The error has seemed to go away (knock on wood) by changing the declaration line to:
character(len=:), dimension(:), allocatable :: inFNs
I'm sorting through another issue in my code before I can know for sure.
In Response to Duplicate Question:
This is not a duplicate of the question suggested for so many reasons that I'm truly confused as to the marking. This question deals specifically with the syntax of an allocatable array of character arrays as opposed to alloctable arrays in general. This question deal with a potential compiler bug with Intel Visual Fortran while the other is a question on differences between Intel Fortran and gFortran. This question deals with a silent crash and heap corruption while attempting to use a separate array whereas the other deals with whether or not the array in question is considered allocated after an operation.
Even more to the point the answer in the second question is irrelevant to the issue present in this question as that option being turned on or off doesn't affect the issue presented.
To say these two questions are identical is like saying I was encountering crash with the following code
real :: number
number = 4.d0
and someone asking another question asking why there is an issue with the following
real :: number
number = 4
call add3ToDouble(number)
subroutine add3ToDouble(a)
real*8 :: a
a = a + 3.d0
end subroutine add3ToDouble
and saying the answer to both being "Because ifort defaults to real(kind=4)"

Allocatable arrays in fortran 77 and gfortran

I'm trying to compile some old fortran77 programs with gfortran and getting error with allocatable arrays.
If I define arrays in f90-style, like:
REAL*8,allocatable::somearray(:)
everything is fine, but in those old programs arrays defined as:
REAL*8 somearray[ALLOCATABLE](:)
which cause gfortran error output:
REAL*8,allocatable::somearray[ALLOCATABLE](:)
1
Fatal Error: Coarrays disabled at (1), use -fcoarray= to enable
I really wish to avoid rewriting whole programs to f90 style, so, could you please tell me, is there any way to force gfortran to compile it?
Thanks a lot.
For standard checking you can use -std flag
-std=std
Specify the standard to which the program is expected to conform, which may be one of f95',f2003', f2008',gnu', or `legacy'.
To "force" gfortran to compile your code, you have to use syntax it recognizes
I'd probably go for search and replace. For example,
sed 's/\(REAL\*8\)[[:blank:]]\+\([^[]\+\)\[ALLOCATABLE\]\(.*\)/\1, allocatable :: \2\3/' <old.source> > <new.source>
where sed is available.
Of course, be careful with sed :).
In any case, as it seems your code was written in some non-standard version of old
Fortran, you'll probably need to make changes in any case.
For what it's worth the Intel Fortran compiler (v13.something) compiles the following micro-program without complaint. This executes and writes 10 to the terminal:
REAL*8 somearray[ALLOCATABLE](:)
allocate(somearray(10))
print *, size(somearray)
end
Given the history of the Intel compiler I suspect that the strange declaration is an extension provided by DEC Fortran, possibly an early implementation of what was later standardised in Fortran 90.

gfortran does not allow character arrays with varying component lengths

See the example below
program test
character(10),dimension(5):: models = (/"feddes.swp", "jarvis89.swp", "jarvis10.swp" , "pem.swp", "van.swp"/)
end
The following error is returned:
Different CHARACTER lengths (10/12) in array constructor at (1)
There is no error with ifort compiler. Why does it happen with gfortran and is there any way to circumvent this problem?
You have some lengths 12 in the constructor, so it may be better to use length 12.
Also, use instead
character(len=12), dimension(5) :: models = [character(len=12) :: "feddes.swp", &
"jarvis89.swp", "jarvis10.swp", "pem.swp", "van.swp"]
Possibly even better, if you have compiler support, is
character(len=*), dimension(*) :: ...
The original code is accepted by ifort but it is not standard fortran, hence the error from gfortran. If you supply the option -std to ifort it will print warnings when the compiler allows extensions such as this.