0

I have a Fortran program that compiles without problems, but then gets an error:

Attempt to call a routine with argument number one as a procedure when a real(kind=2) was required

ROOTS!X_ROOT - in file exercise2base.f90 at line 20 [+0074]

main - in file exercise2base.f90 at line 65 [+00c8]

I don't really know what this means, I thought maybe it means that I pass an argument to some function which is not the right type, but the references that are given don't make sense:

  • line 20 is end function x_rtsmpl
  • line 66 is answer=x_root(bb_integral,l1,l2,epsx,epsf,root_type)

so I don't understand what's going on...

I'm using Silverfrost with Plato IDE.

module roots
  implicit none
  character(20) :: root_type

contains

  function x_rtsmpl(f,x1,x2,epsx,epsf) result(x_root)
    implicit none
    real(2) :: x_root
    real(2), intent(IN) :: x1,x2,epsx,epsf
    interface
      function f(x)
        implicit none
        real(2), intent(IN) :: x
        real(2) :: f
      end function f
    end interface
    real(2) :: xx,fx
    x_root=x1
  end function x_rtsmpl

  function x_root(f,x1,x2,epsx,epsf) result(x_r)
    implicit none
    real(2) :: x_r
    real(2), intent(IN) :: x1,x2,epsx,epsf
    interface
      function f(x)
        implicit none
        real(2), intent(IN) :: x
        real(2) :: f
      end function f
    end interface
      x_r=x_rtsmpl(f,x1,x2,epsx,epsf)
    return
  end function x_root

end module roots

module blackbody
  implicit none
  private
  public :: Ibb

contains
  function Ibb(lambda)
    real(2) , intent (in) :: lambda
    real(2) :: Ibb
    Ibb=lambda+1._2
    return
  end function Ibb

end module blackbody

program master

  use roots
  use blackbody
  implicit none
  real(2) :: l2,epsx,epsf,answer,l1,epsi,requested
  l1=4.d-7
  l2=1.d-4
  epsx=1.d-2*l1
  epsf=1.d-1
  epsi=1.d-4
  answer=x_root(Ibb,l1,l2,epsx,epsf)

end program master

EDIT: The code is now trimmed all the way down to its basic functions with only declarations and simple "dummy" calculations.

agentp
  • 6,849
  • 2
  • 19
  • 37
Yoni
  • 151
  • 5
  • Can you make this much smaller and still exhibit the problem ([mcve])? – francescalus Apr 23 '17 at 15:54
  • @francescalus I don't really understand the core of the problem, so I don't want to exclude stuff that might be relevant. Could you point out (besides the general guidelines) what does the error really mean, and where should I expect to find the cause of the problem for this type of error? I'll try to minimize my code accordingly. – Yoni Apr 23 '17 at 16:02
  • @francescalus I reduced the code. If it still requires trimming tell me and I'll try to reduce it further. – Yoni Apr 23 '17 at 16:19
  • The error message points to the call stack main->`check`->`x_root`->`x_rtsmpl`. You should be able to delete anything unrelated to that. Do it incrementally and when you can delete nothing further without the problem disappearing you've a (hopefully much) smaller example. – francescalus Apr 23 '17 at 17:02
  • @francescalus Okay I think I did just that - removed literally everyting: deleted unrelated functions, replaced needlessly complicated calculations with dummy "x=3" ones and kept (almost) only relevant function declarations. – Yoni Apr 23 '17 at 17:07
  • Well, nothing jumps out at me that fits the error message... It looks like everything is in one file (yes?), so it surprises me a little that the compiler doesn't complain at compile time instead of leaving to run time. Are there compilation options for doing as much checking as possible (around interfaces in particular)? [Equally compilers are generally much better than I am at noticing errors like this.] – francescalus Apr 23 '17 at 17:20
  • @francescalus Indeed everything is in one file, and I haven't found any extra options for more thorough compilation... :( – Yoni Apr 23 '17 at 17:30
  • 1
    there is more to trim. Call `x_root` directly from `master` for example. No reason to open unit 11.. etc. – agentp Apr 23 '17 at 18:16
  • @agentp thank you, I did the extra trimming, I can't think of anything else to remove, because this is really the basic structure, so I hope it's okay – Yoni Apr 23 '17 at 18:44
  • And one pet peeve of mine. `real(2)` is ugly and non-portable. People very often use `real(8) ` and think it is fine and it works in majority of cases. But `real(2)` is even the opposite, it does not compile in most of the compilers. – Vladimir F Героям слава Apr 23 '17 at 18:47
  • @Vladimir I think in Plato using .f90 files it is necessary. 'real(8)' doesn't work in general and raises errors – Yoni Apr 23 '17 at 18:55
  • @The point is both are bad in the same way, both 2 and 8 are not portable. See http://stackoverflow.com/documentation/fortran/939/data-types/4390/precision-of-floating-point-numbers#t=201704231859269443431 and http://stackoverflow.com/questions/838310/fortran-90-kind-parameter?noredirect=1&lq=1 – Vladimir F Героям слава Apr 23 '17 at 19:01
  • @VladimirF hmmm... so what is the alternative? in the links there's a huge list of options. What should I replace 'real(2)' with? – Yoni Apr 23 '17 at 19:09
  • You can choose from those alternatives after you study them and understand how they differ. But you don't need to do that now. Personally, I would use real64 if the compiler supports it. – Vladimir F Героям слава Apr 23 '17 at 19:18
  • I really don't know what is going on in your code. It does not trigger any error in gfortran. – Vladimir F Героям слава Apr 23 '17 at 19:23
  • If you are interested in a workaround, you might make the function external (not in a module/contains) and declare it `external` as needed. – agentp Apr 23 '17 at 20:10
  • Another suggestion is to pass around procedure pointers. To echo Vladimir F's comments, you could just replace the `real(2)`s with `real` (or `double precision`) as I can't imagine that the specific (non-portable) kind number is causing the problem. Oh, and remove `_2` from/replace with `d0` in the literal constants. – francescalus Apr 23 '17 at 22:16

0 Answers0