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

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


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?): 

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

The following small program will raise this error:

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
 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)
end program

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

intrinsic :: random_number 
line then the compiler type checking complains about random_number being undefined.


5 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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:

call neg1to1(rnd_wrap,testvec)
 subroutine rnd_wrap(harvest)
 real(WP) ,intent(out) :: harvest(:)
 call random_number(harvest)
 end subroutine rnd_wrap

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.

Retired 12/31/2016

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.

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.

Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today