Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!

Integer Constant declaration


Quick question.   I know that for real constants, it is recommended to declare as (0.0_dp):

integer, public, parameter :: dp = selected_real_kind(p=15, r=307) 
real(kind=dp) :: real_number = 0.0_dp

What about integer constants?  Assuming i4 has been defined as int32:

delta = b + 1  would become delta b + 1_i4

Should all integer constants be declared using the "integer_i4" format?   If so, does that include:

1. Do loops=>   do I=1_i4, 14_i4  ?

2. Array index =>   array(1_i4)?

3. Format statements =>  fmt='(10_i4f10.5)'?



0 Kudos
1 Reply
Black Belt

Kind specifiers must not appear in format statements.  They are simply not permitted by the syntax rules for format specifications.


Conversion of integer values between kinds, if the value can be represented in both kinds, is precise.

The same isn't true for real values.  For example, if the radix for single and double precision is 2, then the syntax `0.1` and `0.1D0` result in different approximations for the value of one tenth.  A similar problem will occur for large magnitude integral values, that may be within the range of either kind of real, but are large enough such that the spacing between model numbers is greater than one.

This is perhaps the primary reason that you see the recommendation for always specifying the kind of a real on a literal constant - it may change the value used in subsequent computations.

(For integral values of small magnitude, conversion of values between real kinds is also precise.  Zero definitely counts as a small integral value.)

A kind specifier is obviously required when the value cannot be represented in the default kind. 

Kind specifiers may be required where combinations of literal values in terms expression could cause range or precision issues - i.e. `1.0 / 3.0` results in a different approximation to one third than `1.0D0 / 3.0`, even though the values of one and three can be exactly converted between single and double precision.

Kind specifiers may also need to be included when a literal (or a combination of literals in a term in an expression) is used as an actual argument - kinds are required to match when invoking specific procedures, and generic procedure resolution is based on type and kind.

In other circumstances, whether to use a kind specifier or not is perhaps more a question of style.  Because omitting a kind specifier can result in subtle numerical errors, some people prefer to never rely on the implicit conversion between kinds (or between numeric types) and always write kind consistent expressions.  For expressions and assignment that might be reasonable - for your do loop (loop parameters are implicitly converted to the kind of the do variable) and array subscript case I think that just results in syntax noise.