J3/14-220
To: J3
From: Nick Maclaren
Subject: Interpretation of values of type C_BOOL
Date: 2014 August 07
----------------------------------------------------------------------
NUMBER: TBD
TITLE: Interpretation of values of type C_BOOL
KEYWORD: C_BOOL
DEFECT TYPE: Clarification
STATUS: J3 consideration in progress
In all cases except question 2, they assume that the companion processor
supports more than one value bit for the C type _Bool or allows padding
bits to be set. Most C compilers do one of those.
QUESTION 1:
If a Fortran variable of type LOGICAL(C_BOOL) is passed to a C function,
is the Fortran processor required to represent .TRUE._C_BOOL by all bits
zero except the one required bit?
QUESTION 2:
If a processor and its companion processor support a negative integer
zero, is the Fortran processor required to represent .FALSE._C_BOOL by
all bits zero?
QUESTION 3:
Is a companion processor allowed to return a non-zero value other than
all bits zero except the least significant as an object of type
LOGICAL(C_BOOL)? And, if it allowed to, is a Fortran processor required
to treat it as equivalent to .TRUE._C_BOOL?
QUESTION 4:
Is a companion processor allowed to return a zero value other than with
all bits zero as an object of type LOGICAL(C_BOOL)? And, if it is
allowed to, is a Fortran processor required to treat it as equivalent to
.FALSE._C_BOOL?
EXAMPLE:
The following is an example program for questions 3 and 4 that may
be used for testing. Of the compilers I have access to, I have seen
'T T T T F 0 1/T T T T F 0 1', 'F F F F T 0 1/F F F F T 0 1' and
'T T F T T 0 1/T T F T T 0 1'.
Fortran:
PROGRAM Main
USE ISO_C_BINDING
INTERFACE
SUBROUTINE Fred (a, b, c, d, e) BIND(C,NAME="Fred")
USE ISO_C_BINDING
LOGICAL(C_BOOL), INTENT(OUT) :: a, b
INTEGER(C_INT), INTENT(OUT) :: c, d
LOGICAL(C_BOOL), VALUE :: e
END SUBROUTINE Fred
END INTERFACE
LOGICAL(C_BOOL) :: a, b
INTEGER(C_INT) :: c, d
CALL Fred(a,b,c,d,.FALSE._C_BOOL)
PRINT *, a, b, a.AND.b, a.OR.b, a.EQV.b, c, d
CALL Fred(a,b,c,d,.TRUE._C_BOOL)
PRINT *, a, b, a.AND.b, a.OR.b, a.EQV.b, c, d
END PROGRAM Main
C:
void Fred (_Bool *a, _Bool *b, int *c, int *d, _Bool e) {
if (e) {
*(unsigned char *)a = 2;
*(unsigned char *)b = 4;
} else {
*(unsigned char *)a = 128;
*(unsigned char *)b = 64;
}
*c = *a&*b;
*d = (*a && *b);
}
DISCUSSION:
ISO/IEC 9899:2011 is referred to as C11 in this paper.
In C, the canonical values for true and false for type _Bool are 1 and
(positive) 0, respectively (C11 7.18p2,3), and any other value is
replaced by one of those when converted to a _Bool (C11 6.3.1.2p1).
These are all bits zero except the least significant, and all bits zero.
However, those are only the canonical values, and other values may also
be valid representations of true and false, even in objects of type _Bool.
A _Bool is an integer type made up of at least one byte (C11 6.2.5p6,
6.2.6.1p2), a conforming compiler may allow it to hold other values (C11
4p6,7, note 5, 6.2.6.2p2), and there are several strictly conforming
ways to store other values in a _Bool variable, though it is unclear
whether there are any strictly conforming ways to use it as a value (C11
6.2.6.1p5 and footnotes 50 and 122). C11 6.2.5p2 was raised in this
context during the standardisation of C99, and the general agreement in
WG14 was that it was relevant solely to 6.7.2.1p11.
A value of type _Bool, when used as a truth value, is treated as true if
it is non-zero and false otherwise (C11 6.3.1.1p2, 6.5.9p4, 6.5.15p4,
6.8.4.1p2). Therefore any other non-zero value will be treated as
representing true, unless it represents a trap representation.
Also, systems may support a negative integer zero, if they use signed
magnitude or ones' complement (C11 6.2.6.2p2,3). Again, C requires that
to be treated as representing false, unless it represents a trap
representation. This is implementation-defined.
Padding bits are not value bits and how they are used is unspecified
(C11 6.2.6.2p1). These are ignored (C11 6.2.6.1p4 and footnote 53)
unless they specify a trap reresentation; however, they can be set by
treating the object as an array of unsigned char.
The result of this is that it is possible (in most implementations) to
have two objects of type _Bool, a and b, that evaluate as true in
truth-value contexts, but where (say) a&b evaluates as false.
Some Fortran compilers used to use and probably still do use values
other than 0 and 1 for LOGICAL, and it is simpler and more efficient for
them to pass the values over unchanged. Questions 1 and 2 ask
whether that is allowed.
Questions 3 and 4 ask whether, if a companion processor can produce
other values that are not trap representations, a Fortran processor is
required to treat them as representing .TRUE. and .FALSE., or is
allowed to treat them as C treats variables of type _Bool.
ANSWER:
Awaiting statement of direction.
EDITS:
Awaiting statement of direction.
SUBMITTED BY: Nick Maclaren
HISTORY: m205 14-nnn Submitted