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

Subroutine with undefined input variables

jaeger0
Beginner
1,290 Views
Hi

I'm writing a Subroitine to proof the validity of certain variables. If they exceed the limit, then a warning, or error is given.
Further the values are restricted set to its max/min range.
Subroutine Proof_values(value, range, exceeding)
type(t_range) range
! input/output
integer(4) value
! output
integer exceeding

exceeding = 0

if (value .GT. range%max) then
exceeding = 2
value = range%max
endif
..


So I have different types of variables Integer2..8, real4..8
I don't want to write the subroutine for each of the different datatypes, so is there a posibility to apply the subroutine for
the different datatypes ?
0 Kudos
9 Replies
onkelhotte
New Contributor II
1,290 Views
Quoting - jaeger0
Hi

I'm writing a Subroitine to proof the validity of certain variables. If they exceed the limit, then a warning, or error is given.
Further the values are restricted set to its max/min range.
Subroutine Proof_values(value, range, exceeding)
type(t_range) range
! input/output
integer(4) value
! output
integer exceeding

exceeding = 0

if (value .GT. range%max) then
exceeding = 2
value = range%max
endif
..


So I have different types of variables Integer2..8, real4..8
I don't want to write the subroutine for each of the different datatypes, so is there a posibility to apply the subroutine for
the different datatypes ?

Unlike C++/C#/Java... where you can overload methods, Fortran does not have such a feature.

What you can do is to build your subroutine with a kind=8 type and when you use it, you useint8 or real8 to convert it to the required type.

Markus
0 Kudos
jaeger0
Beginner
1,290 Views
Quoting - onkelhotte

Unlike C++/C#/Java... where you can overload methods, Fortran does not have such a feature.

What you can do is to build your subroutine with a kind=8 type and when you use it, you useint8 or real8 to convert it to the required type.

Markus

ok I see,

but, lets set
real(kind=8) value

and then

integer(2) age

call Proof_values(dble(age), ...)

this will pass the input value correctly, but not the output value. If I internally set
the value, then it is not passed to the output correctly

I don't want to change all variables to real(8) for generality.

I re-wrote the subroutine to

Proof_values(value,out_value, ..)
outvalue= value

if (value .GT. range%max) then
out_value = range%max
...

call Proof_values(dble(age),out_val, ..)
age = outval


But this does not look nice !!
Is there any other possibility ?



0 Kudos
Les_Neilson
Valued Contributor II
1,290 Views
Quoting - jaeger0
Is there any other possibility ?


You could take a look at generic procedures (subroutines or functions) (see in the help).
All of your calls in the rest of the codewould be to the generic name, and the arguments would determine which specific routine is actually called. You would have to write the specifics for each type (integer, real, etc) but onlyneed to do it once.

Les
0 Kudos
jaeger0
Beginner
1,290 Views
Quoting - Les Neilson

You could take a look at generic procedures (subroutines or functions) (see in the help).
All of your calls in the rest of the codewould be to the generic name, and the arguments would determine which specific routine is actually called. You would have to write the specifics for each type (integer, real, etc) but onlyneed to do it once.

Les

Thanks

I think I understand the help/example. However I don't really understand how to systax it.
For the example

I get the error "the type of actual argument differs from the type of dummy" for line "call proof(a, 2)"
Furter I want tho have a Type variable, but this is not possible in the Interface
Any suggestions ??




module PROOF


contains

subroutine proof(val,thr)
interface
subroutine real8_sub(val,thr)
real(8) val,thr
end subroutine
subroutine int4_sub(val,thr)
integer(4) val,thr
end subroutine
! subroutine int_sub(val,thr)
! integer(4) val
! type(Dlg_ValueRange) no types allowed ??
! end subroutine
end interface

if (val .GT. thr) val=thr

end subroutine
end module


program TEST
USE PROOF
integer a
real b

call proof(a, 2)
call proof(b, 3.5)
end


0 Kudos
jimdempseyatthecove
Honored Contributor III
1,290 Views

proof is declared with an interface using "integer(4)" but is being called with arguments of "integer"

Jim Dempsey
0 Kudos
jaeger0
Beginner
1,290 Views

proof is declared with an interface using "integer(4)" but is being called with arguments of "integer"

Jim Dempsey


I changed the input datatype to integer(4) => Same error
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,290 Views

"2" is "integer" not "integer(4)". Try "2_4"

Jim
0 Kudos
jaeger0
Beginner
1,290 Views

"2" is "integer" not "integer(4)". Try "2_4"

Jim


I understand, but the error remains

integer(4) a,c

call Proof(a,c) => Err1 "the type of actual.. ..argument ; Err2 "the ..argument
call Proof(a,2.5) => Err1 "the type of actual.. ..argument

call Proof(1.0, 2.5) => no Error !!
something else is maybe wrong
0 Kudos
Steven_L_Intel1
Employee
1,290 Views
First of all, INTEGER is INTEGER(4) by default and 2 is the same as 2_4 by default.

The real problem is that you have not written a generic interface, plus you are passing REAL(4) arguments but have defined only a routine that accepts REAL(8). Here's an example that works (ignoring for now that val is uninitialized in each of the calls).

[plain]module PROOF_MOD

interface proof
module procedure real4_sub
module procedure real8_sub
module procedure int4_sub
end interface

contains

subroutine real4_sub(val,thr)
real(4) val,thr
if (val .GT. thr) val=thr
end subroutine

subroutine real8_sub(val,thr)
real(8) val,thr
if (val .GT. thr) val=thr
end subroutine

subroutine int4_sub(val,thr)
integer(4) val,thr
if (val .GT. thr) val=thr
end subroutine
end module


program TEST
USE PROOF_MOD
integer a
real b

call proof(a, 2)
call proof(b, 3.5)
end[/plain]

You can't give the same name to a module and a generic procedure so I renamed the module.
0 Kudos
Reply