The program
module primes_mod
implicit none
contains
pure function arange(imin, imax) result(r)
! Create an integer array [imin, imin+1, ..., imax] using an explicit loop.
integer, intent(in) :: imin, imax
integer, allocatable :: r(:)
integer :: n, i
n = imax - imin + 1
allocate(r(n))
if (n < 1) return
r(1) = imin
do i = 2, n
r(i) = r(i-1) + 1
end do
end function arange
pure recursive function sieve(a) result(primes)
! Recursively sieve an integer array to extract primes
integer, intent(in) :: a(:)
integer, allocatable :: primes(:), rest(:)
if (size(a) == 0) then
primes = [integer ::]
else
rest = pack(a(2:), mod(a(2:), a(1)) /= 0)
primes = [a(1), sieve(rest)]
end if
end function sieve
pure function primes(n) result(prs)
integer, intent(in) :: n
integer, allocatable :: prs(:)
prs = sieve(arange(2, n))
end function primes
end module primes_mod
program compute_primes
use primes_mod, only: primes
implicit none
integer, parameter :: n = 10**7
integer, allocatable :: v(:)
integer :: nv
v = primes(n)
nv = size(v)
print "(a,i0,':',*(1x,i0))", "# primes, last prime up to ", n, nv, v(nv)
end program compute_primes
compiled with gfortran -O2 primes.f90 -Wl,--stack,134217728
on Windows hangs. There is no problem if a non-recursive approach is used, as in
this code
module primes_mod
implicit none
public :: primes
contains
function primes(n) result(prime_list)
integer, intent(in) :: n
integer, allocatable :: prime_list(
logical, allocatable :: is_prime(
integer :: i, j, num_primes
if (n < 2) then
allocate(prime_list(0))
return
end if
! mark all numbers 1..n as prime (temporarily)
allocate(is_prime(n), source=.true.)
is_prime(1) = .false. ! 1 is not prime
! sieve: eliminate multiples
do i = 2, int(sqrt(real(n)))
if (is_prime(i)) is_prime(i**2:n:i) = .false.
end do
! count primes and collect them
num_primes = count(is_prime)
allocate(prime_list(num_primes))
num_primes = 0
do i = 1, n
if (is_prime(i)) then
num_primes = num_primes + 1
prime_list(num_primes) = i
end if
end do
end function primes
end module primes_mod
program compute_primes
use primes_mod, only: primes
implicit none
integer, parameter :: n = 10**7
integer, allocatable :: v(
integer :: nv
v = primes(n)
nv = size(v)
print “(a,i0,‘:’,*(1x,i0))”, "# primes, last prime up to ", n, nv, v(nv)
end program compute_primes
Is there a different compiler option I should use, or is the moral not to use a recursive approach if the recursion depth may be high, at least on Windows?