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

Generic procedures and -real_size switch

mhermanns
Beginner
737 Views
Hi to everybody,

In my F90 program I use generic procedures. An unexpected behaviour I have found in ifort 9.0 (maybe in others, I have not tried) is shown in the following example:

!---------------------------------!
module Mod_Example
implicit none

interface Generic_Procedure
module procedure Specific_Procedure
end interface Generic_Procedure

contains
!---------------------------------!
subroutine Specific_Procedure(x)
real, intent(in) :: x

write(*,*) x

end subroutine Specific_Procedure
!---------------------------------!
end module Mod_Example
!---------------------------------!
!---------------------------------!
program Example_Program
use Mod_Example
implicit none

call Generic_Procedure(0d0)

end program Example_Program
!---------------------------------!

When compiled using the command "ifort -real_size 64 example.f90" everything works fine, but if I use the command "ifort -real_size 32 example.f90" instead, then the following error message shows:

fortcom: Error: example.f90, line 25: There is no matching specific subroutine for this generic subroutine call. [GENERIC_PROCEDURE]
call Generic_Procedure(0d0)
-----^
compilation aborted for example.f90 (code 1)

The error message is clear, but what I don't understand is that if the switch "-real_size 32" defines the size of real constants, why is 0d0 not changed to 0.0 during compilation time.

Should the correct way of doing this be to use "0.0" or "0e0" and if I want everything in double precision to use the "-real_size 64" switch?

This brings me to another question which always pops up in my mind. If I specify numbers as 0.0 or 0e0 and compile the code using -r8, how will the constant be promoted to double precision? I remember in the past to have heard once that to assign a single precision constant to a double precision variable does not lead to the expected result (the last 8 digits are "randomly" assigned).

The question could be made in a different way. If I want to control the precision of real and integers using compiler switches, how should I specify numerical constants in the program?

Hope somebody can help me clear my mind :-). Thanks in advance and greetings from Spain,

Miguel Hermanns
0 Kudos
5 Replies
Steven_L_Intel1
Employee
737 Views
You already have figured out the answer. 0D0 is a double precision constant and is not affected by -real_size. Use simply 0.0 for a constant of type "default real".
0 Kudos
mhermanns
Beginner
737 Views
Thanks for the info, Steve.

Only one thing remains unclear for me, namely what should one use for instance instead of 1d-6? I hope not 0.000001, or?

Thanks again,

Miguel
0 Kudos
TimP
Honored Contributor III
737 Views
If you prefer pre-f90 syntax for constants, and don't like to use PARAMETER constants, 1e-6 should work. I don't think any actively maintained compilers remain which don't accept f90 syntax.
0 Kudos
mhermanns
Beginner
737 Views
Thanks Tim,

What do you mean with "pre-f90 syntax" and "f90 syntax"? I was not aware about a change in that sense. About using PARAMETER I'm of those that think it is more clear to put in an equation a number as such than to put a text saying "one" or "zero" or similar :-).

Greetings from Spain,

Miguel
0 Kudos
Steven_L_Intel1
Employee
737 Views
1e-6 is fine and is of type "default real". 1d-6 is of type "double precision". What Tim was hinting at was that the generally accepted method as of Fortran 90 is to use kind specifiers, such as 1e-6_DP if you want double precision, where DP is a parameter constant you define earlier with something like this:

integer, parameter :: DP = SELECTED_REAL_KIND(14)

Note that if you do this, then -real_size won't affect it. The general advice nowadays is to not use switches but to define the parameter consstants as you want them and to use them consistently.
0 Kudos
Reply