Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28602 Discussions

[RANDOM_NUMBER] error #6551: This intrinsic procedure cannot be passed as an actual argument.

Izaak_Beekman
New Contributor II
541 Views

Hi,

Can someone please explain the following error to me (Is passing this intrinsic as an actual argument in violation of the Fortran standard, and if not, why won't ifort let me do it?): 

[plain]error #6551: This intrinsic procedure cannot be passed as an actual argument.   [RANDOM_NUMBER][/plain]

The following small program will raise this error:

[fortran]

module mymod
implicit none
integer ,parameter :: WP = kind(1.0D0)
abstract interface
subroutine RanVec(harvest)
import :: WP
real(WP) ,intent(out) :: harvest(:)
end subroutine
end interface
contains
subroutine neg1to1(Ran,harvest)
procedure(RanVec) :: Ran
real(WP) ,intent(out) :: harvest(:)

call Ran(harvest)
harvest = harvest*2 - 1.0_WP
end subroutine neg1to1
end module mymod
program bugtest
use mymod
implicit none
intrinsic :: random_number
real(WP) :: testvec(100)

call neg1to1(random_number,testvec)

print*,testvec
end program

[/fortran]

I am writing code to map random uniformly distributed variates onto normaly distributed variates. It would be nice for the user to be able to pass his or her user defined PRNG to the routine or Fortran's intrinsic PRNG, random_number. Note that, if I don't include the [fortran]intrinsic :: random_number [/fortran] line then the compiler type checking complains about random_number being undefined.

Thanks,

0 Kudos
4 Replies
mecej4
Honored Contributor III
541 Views

You cannot pass intrinsic procedure names as if they are external names. An easy workaround is to wrap the intrinsic in a procedure, either an external one or a CONTAINed one. For example, add before the last line of your program:

[fortran]

call neg1to1(rnd_wrap,testvec)
print*,testvec

contains
subroutine rnd_wrap(harvest)
real(WP) ,intent(out) :: harvest(:)
call random_number(harvest)
return
end subroutine rnd_wrap

[/fortran]

0 Kudos
Steven_L_Intel1
Employee
541 Views
You can pass many intrinsic functions as actual arguments, but this is mainly limited to those found in Fortran 77, and not all of those. For example, SQRT is ok, INT is not. The Fortran standard has a table of intrinsics where it notes those that may be passed with a "bullet". New entries have not been added to this list.
0 Kudos
Izaak_Beekman
New Contributor II
541 Views

Good to know, thanks Steve. I guess, since random_number is not PURE, stateless, etc. it makes sense that additional restrictions might be placed on it.

0 Kudos
Steven_L_Intel1
Employee
541 Views

In general, this isn't related to whether it is PURE or not. The addition of generics complicates the idea of passing an intrinsic, as you have to decide which one. The committee felt, reasonably, that this was a not-very-useful feature and chose to not extend it past what Fortran 77 allowed. RANDOM_NUMBER is generic as well.

0 Kudos
Reply