To: J3 J3/19-212r1
From: Bill Long
Subject: US-23 Part 2, Standardizing use of BOZ constants
Date: 2019-August-09
Reference: 19-132
Discussion:
-----------
This paper describes Part 2 (of 3) of the BITS proposal, US-23.
Several common extensions for the usage of BOZ constants violate the
constraint
C7109 (R764) A boz-literal-constant shall appear only as a
data-stmt-constant in a DATA statement, or where
explicitly allowed in 16.9 as an actual argument of an
intrinsic procedure.
Several of the requests that lead to the proposal US-23 were actually
cases where usage of these sorts of extensions lead to nonportable
code. A side effect of adopting the full BITS data type is to
automatically make these uses conforming with portable syntax and
semantics. However, a much smaller change is to relax C7109 and
specify semantics for several usages of BOZ constants corresponding to
commonly implemented extensions.
These extensions include a BOZ constant as the expr in an intrinsic
assignment where the variable is of type INTEGER or REAL. If Table
10.8 Intrinsic assignment type conformance in 10.2.1.2 Intrinsic
assignment statement is expanded to permit BOZ constants for "Type of
expr" in the integer and real rows, then the rules in Table 10.9
Numeric conversion and the assignment statement specify the expected
interpretation since BOZ constants are already allowed as the expr
argument to both the INT and REAL intrinsics.
In addition to assignment (and the corresponding initializations of
named constants), the proposal is to allow array constructors that
include a type specification, and the appearance of BOZ constants as
I/O list items in a WRITE statement.
Requirements
------------
Allow the following usage of BOZ constants beyond what is allowed in
C7109, as follows:
A: BOZ as an initialization in the definition of an integer named
constant.
B: BOZ as an initialization in the definition of a real named
constant.
C: BOZ as the expr of an intrinsic assignment to an variable of type
INTEGER.
D: BOZ as the expr of an intrinsic assignment to an variable of type
REAL.
E: BOZ constants that each have the same number of bits as ac-values
with a type-spec of INTEGER.
F: BOZ constants that each have the same number of bits as ac-values
with a type-spec of REAL. Each ac-value must have a bit sequence
that is a valid representation for a value of the specified KIND of
REAL.
G: BOZ constant as an output-item in a WRITE statement corresponding to
a B, O, or Z format edit descriptor.
A simple test program compiled with various compiler reveals the
existing support for these extensions:
A B C D E F G
Cray Y Y Y Y Y Y Y
Fujitsu Y Y Y Y Y Y N
gfortran Y Y Y Y Y N Y
IBM Y Y Y Y Y Y Y
Intel Y Y Y Y N N Y
PGI Y Y Y Y Y Y Y
Notes: gfortran requires the -fno-range-check option to compile the
test code.
PGI required replacement of the MASKL reference with an
equivalent shift operation.
Fujitsu required wrapping the output list items in INT()
references
Otherwise all of the compilers compiled the test code with no extra
options and without any error messages and the resulting program
executed with compare test successor failure as shown above.
The program:
program test_bits
use,intrinsic :: iso_fortran_env, only:int64, real64
implicit none
! A: Define integer with largest magnitude negative number,
! (also a sign-bit mask)
integer(int64),parameter :: lbmask = Z"8000000000000000"
integer(int64),parameter :: lbmask1 = maskl(1, int64)
! B: Define reals using BOZ constants
real(real64),parameter :: one = Z"3FF0000000000000"
real(real64),parameter :: two = Z"4000000000000000"
real(real64),parameter :: three = Z"4008000000000000"
integer(int64) :: i,j,k,l,m,n(3)
real(real64) :: a,b,c,d(3)
write (*,100) "Value ", lbmask, " should be equal to ", lbmask1
write (*,100) "Got : ",one, " Expected: ", 1.0_real64
write (*,100) "Got : ",two, " Expected: ", 2.0_real64
write (*,100) "Got : ",three, " Expected: ", 3.0_real64
! Use of BOZ constants as arguments to bitwise operations
! (This is already conforming, included as a check.)
i = 7
j = iand (i, z"0000000000000003")
write (*, 100) "Got : ", j, " Expected: ", 3
! C: Intrinsic assignment to integer with expr a BOZ constant
k = Z"1010101010101010"
! D: Intrinsic assignment to real with expr a BOZ constant
write (*,100) "Got : ",k, " Expected: ", Z"1010101010101010"
a = Z"3FF0000000000000"
write (*,100) "Got : ", a, " Expected: ", 1.0_real64
! E: Array constructor in intrinsic assignment to integer
n = [integer(int64) :: Z"1111111111111111", &
Z"2222222222222222",Z"3333333333333333"]
write (*,100) "Got : ", n(1), " Expected: ",Z"1111111111111111"
write (*,100) "Got : ", n(2), " Expected: ",Z"2222222222222222"
write (*,100) "Got : ", n(3), " Expected: ",Z"3333333333333333"
! F: Array constructor in intrinsic assignment to real
d = [real(real64) :: Z"3FF0000000000000", &
Z"4000000000000000", Z"4008000000000000"]
write (*,100) "Got :", d(1), " Expected: ",Z"3FF0000000000000"
write (*,100) "Got :", d(2), " Expected: ",Z"4000000000000000"
write (*,100) "Got :", d(3), " Expected: ",Z"4008000000000000"
100 format (a,Z18.16, a, z18.16)
end program test_bits
Sematics and Syntax
-------------------
(to be supplied)
Edits to 18-007r1
-----------------
(to be supplied)