kurdayon@xxxxxxxxx wrote:
Hello,
Can anybody explain what is happening with the following code?
program p1
implicit none
real a, b
real, dimension(5) :: y, x, d
real, dimension(:,:) :: f
allocate(f(2,5))
x = (/1.0, 2.0, 3.0, 4.0, 5.0/)
y = (/1.0, 2.0, 3.0, 4.0, 5.0/)
call spectrum(a, b, y, d, f)
end program p1
subroutine spectrum(a, b, y, d, f)
implicit none
real a, b
real, dimension(:) :: y, d
real, dimension(:,:) :: f
If you use a subroutine that has an assumed shape array,
which is what y, d, and f are, you must have an explicit
interface to the subroutine. There are a few ways to do
this, but in my opinion, the best way is to use modules.
It's also my opinion, that everybody should get in the
habit of putting all of there subroutines in modules.
There are several cases where an interface is required,
and it's just easier to do it all the time and not try
to remember which case applies when. Also, modules
force the compiler to do a better job of error checking
on subroutine calls.
See below for what to do. You'll need to compile the
module before you compile the program.
write(6,*) 'Hello !!!'
end subroutine spectrum
It gives "Segmentation fault".
Why does it work if I comment assignment to x?
program p1
use some_module_name
implicit none
real a, b
real, dimension(5) :: y, x, d
real, dimension(:,:) :: f
allocate(f(2,5))
! x = (/1.0, 2.0, 3.0, 4.0, 5.0/) <-- take a look here!
y = (/1.0, 2.0, 3.0, 4.0, 5.0/)
call spectrum(a, b, y, d, f)
end program p1
module some_module_name
contains
subroutine spectrum(a, b, y, d, f)
implicit none
real a, b
real, dimension(:) :: y, d
real, dimension(:,:) :: f
write(6,*) 'Hello !!!'
end subroutine spectrum
end module
Why does it work if I remove one of the arguments argument from
subroutine?
It's pure luck how or when it works. When you have an
assumed shape array, the compiler must pass some sort
of dimension information for the arrays. When spectrum
is run, it looks for this information where it expects it
to be. Because there was no explicit interface in the
program, the call did not pass the dimension information.
So, when spectrum looked for it (on the stack) it found
a set of random numbers and used them for addressing
the arrays. Segmentation fault is a likely thing to
happen, but it's not guaranteed.
*** Hendrickson
program p1
implicit none
real a, b
real, dimension(5) :: y, x, d
real, dimension(:,:) :: f
allocate(f(2,5))
x = (/1.0, 2.0, 3.0, 4.0, 5.0/)
y = (/1.0, 2.0, 3.0, 4.0, 5.0/)
call spectrum(b, y, d, f)
end program p1
subroutine spectrum(b, y, d, f)
implicit none
real a, b
real, dimension(:) :: y, d
real, dimension(:,:) :: f
write(6,*) 'Hello !!!'
end subroutine spectrum
It also works if I remove instead of "a" "b" or "f". Why?