On 12/31/19 11:46 AM, Ned Latham wrote:
> �� Tiib wrote:
>> Ned Latham wrote:
...
>> [conv.bool]
>> "A zero value, null pointer value, or null member pointer value is
>> converted to false; any other value is converted to true."
>
> News to me. Might be because I'm a lazy reader or because my references
> are out of date: Kernigan and Ritchie for C (ANSI 2) and Stroustrup
> (Edition 3) for C++. Both 1990s.
Yes, those sources are thirty years out of date. bool didn't even exist
in K&R C, and if conditions were and are handled differently. In first
edition of K&R C, it says "The unary negation operator ! converts a
non-zero or true operand into 0, and a zero or false operand into l."
However, the second edition came out shortly before the C89 was
approved, and used wording closer to that of the soon-to-be approved
standard: "The operand of the ! operator must have arithmetic type or be
a pointer, and the result is 1 if the value of its operand compares
equal to 0, and 0 otherwise." (A.7.4.7). The key issue may is the phrase
"compares equal to". What happens when a pointer value is compared for
equality with 0? Comparison for equality is covered by A.7.10, and for
the special case where a pointer is "compared to a constant integral
expression with a value of 0", it cross-references A.6.6. That
paragraphs indicates that comparison operators are one way in which an
integral constant expression with a value of 0 gets converted to pointer
type, and it specifies that "This produces a null pointer that is equal
to another null pointer of the same type, but unequal to any pointer to
a function or object."
Thus, !array has the value !(array==0), and array==0 has a value of true
if array is a null pointer, and 1 if it does not, completely independent
of how null pointers are represented.
That is exactly the way the same issue is handled in all later versions
of the C standard.
My copy of Stroustrup disappeared a long time ago. My copy of the C++98
standard was saved on a hard disk which crashed. The oldest version of
the standard I can locate is C++2011. As of that version, the relevant
issues were addressed in the same fashion as in the current version: the
unary ! is described in terms of inverting the result of a conversion to
bool, and the rules for conversion to bool specify that null pointer
values get converted to false. Thus, the result is guaranteed to be
false for null pointer values, regardless of how they are represented.
I'm curious: how does the description of these issues in your copy of
Stroustrup differ from those descriptions? With the preceding C standard
and the following C++ standards so carefully written to produce results
that are independent of how null pointers are represented, it would seem
very odd if that version of C++ was defined in a way which did depend
upon the representation.
>> It does not say that bit-wise checks are made,
>
> If NULL == 0, bitwise checks aren't required, just a check of the
> Z flag of the register that received the return.
How would that work? If null pointer values are, for instance,
represented by having all bits set to 1 (as has actually been done by at
least one implementation), NULL == 0 will still be true - the standard
requires it to be.
I suspect that your comments are specific to a particular architecture,
one for which "all bits 1" would not be a suitable choice for null
pointers. It was a very natural choice on the platform where that
representation was actually used.