Skip to content

Default KINDs for constants and intrinsics #78

@FortranFan

Description

@FortranFan

A proposal from UK national body from year 2013: https://wg5-fortran.org/N1951-N2000/N1975.txt

--------------------------------------------------------------------------
Number: UK-01
Title: Default KINDs for constants and intrinsics
Status: For Consideration
Basic Functionality:
Program-specified default KIND for constants etc.
Rationale:
(a) In the 64-bit world default integer generally being 32-bit is
    increasingly leading to incorrect programs.
(b) In the floating-point world default real generally being 32-bit
    not infrequently leads to incorrect programs.
(c) It is tedious and error-prone to have to attach kind_param's to
    individual literal constants.
(d) It is tedious and error-prone to have to specify a KIND= argument as
    required for each individual reference to an intrinsic function.
(e) Program specification of the default type parameters is possible for
    derived types but not intrinsic types.

Specification (requirements):
1. Provide a mechanism for specifying the default kind parameter for the
   intrinsic types REAL and INTEGER.
2. Decouple the concepts of "default kind" from those of "single precision"
   and "basic integer"; "default kind" to be used for literal constants,
   implicit typing, etc., while "single precision" et al to be used for the
   old storage association contexts.

Discussion:

Specifications (detailed):
--------------------------
a. There will be a new statement, that can appear only between the USE
   statements and IMPLICIT statements, to specify the default kind for a
   particular intrinsic type.
b. The effect of this statement is to change the default kind for the
   remainder of the scoping unit.  To avoid circular dependencies, it does
   not affect the default kind of literals appearing in or before the
   statement itself, nor does it affect the type implied by a PARAMETER
   statement that appears before the statement.
   Rationale: circular dependencies bad, named constants good.
c. The default kind setting in a scoping unit is initially that of its
   host scoping unit; note that as nested scoping units appear necessarily
   after any IMPLICIT statements, this will inherit the user setting.
d. In the case of REAL, the default kind for COMPLEX is also affected.
   It does not affect double precision kind, which remains as twice single
   precision in storage.
e. Terminology:
     "default kind" = user-specifiable default kind
     "single precision kind" = old default real kind
     "basic integer kind" = old default integer kind
f. OPTIONAL: There is a reasonable argument to be made that permitting the
   user to specify the kind for "double precision" constants and variables
   would also be valuable.
g. Table of places where "default kind" is used, and what that should
   correspond to in the new scheme, follows.

    Context                                         Should be
    ---------------------------------------------------------
(1) integer literal with no <kind-param>            default kind
(2) "kindly" intrinsics with absent KIND=           default kind * Note T0
(3) intrinsics with no KIND argument                default kind * Note T1
(4) <type-spec> with no KIND parameter, e.g. REAL   default kind * Note T2
(5) arguments to generic intrinsics                 accept both * Note T3
(6) args/result for specific intrinsics, e.g. AMIN1 basic kind * Note T4
(7) constants in ISO_FORTRAN_ENV                    basic kind * Note T5
(8) having the size of one numeric storage unit     basic kind
(9) EQUIVALENCE/COMMON real/integer matching        basic kind

Note T0.
  This includes LBOUND, LCOBOUND, SIZE, SHAPE ... i.e. all the ones that
  have a KIND= argument and return a REAL/INTEGER/COMPLEX result of the
  specified kind when present, and default kind when not.

Note T1.
  Actually these don't really matter much, as the value always fits into
  basic kind.  However, it would be more convenient when passing as an
  actual argument, and more consistent, for these to be the new
  user-specifiable default kind too.  Here is a representative list of
  the intrinsics concerned: DIGITS, PRECISION, RANGE, EXPONENT,
  MAX_EXPONENT, and THIS_IMAGE.

Note T2.
  Wherever the <type-spec> is, viz a type declaration statement, component
  definition statement, array constructor, etc.

Note T3.
  The affected intrinsics:arguments are DATE_AND_TIME: VALUE,
  EXECUTE_COMMAND_LINE:EXITSTAT,CMDSTAT, GET_COMMAND:LENGTH,STATUS, and
  similar.  Not a big deal (values always representable in the basic kind)
  but why not relax the requirement to permit larger kinds always anyway?

Note T4.
  Not actually important.  These are wholly redundant anyway.

Note T5.
  As if it were a user-defined module with those constants.

Syntax (illustrative):
----------------------
   DEFAULT <intrinsic-type-name> ( [ KIND = ] <int-constant-expr> )
     where <intrinsic-type-name> is INTEGER or REAL.
   Cnnn (Ryyy) The kind number specified in a DEFAULT INTEGER statement
     shall specify a kind whose storage size is at least as great as that
     of basic integer kind.
   {Reason: To stop the user shooting his foot off with a short integer
            kind.}

   OPTIONAL: If we permit specification of double precision kind, add this
             additional syntax:
   DEFAULT DOUBLE PRECISION ( [ KIND = ] <int-constant-expr> )
   Cnnn The kind number specified in a DEFAULT DOUBLE PRECISION
     statement shall not specify a kind whose storage size is less than
     that of default real kind.
   {Reason: There might not be a bigger real kind than the user-specified
            default, but it would be counter-intuitive to permit
            specification of a double precision kind that is actually
            smaller than default real.}

Example:
--------
This is just to show how it works, it is too trivial to show much
advantage.

Program sum_tan_prefix
  Default Integer (Kind=Selected_Int_Kind(18))
  Default Real (Kind=Selected_Real_Kind(15))
  Real,Allocatable :: x(:)
  Print *,'Input vector length N'
  Read *, n
  If (n<2) Stop 'Don''t be silly.'
  Allocate(x(n))
  Print *,'Input vector with',Size(x),'values in degrees'
  Read *,x
  tmp = 0
  Print *,'SUM_TAN_PREFIX results'
  Do i=1,Size(x)
    tmp = tmp + Tan(x(i)*3.1415926535897932384/180)
    Print *,i,x
  End Do
End Program

Metadata

Metadata

Assignees

No one assigned

    Labels

    Clause 7Standard Clause 7: Types

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions