> On Mar 30, 2016, at 3:11 , Jeremy Pereira via swift-evolution
> <swift-evolution@swift.org> wrote:
>
>
>> On 25 Mar 2016, at 23:00, Brent Royal-Gordon via swift-evolution
>> <swift-evolution@swift.org> wrote:
>>
>>> In the low level world, there is no such thing as an invalid address; both
>>> 0x0 and ~0x0 are perfectly valid byte pointers. So using something else
>>> than 0x0 for Swift invalid pointer just shuffle the problem around.
>>
>> Let me state it this way: You cannot write a fully-conforming C compiler for
>> a platform which does not have some way to represent an invalid pointer.
>
> This is not true.
>
> In both C99 and C11, the result of dereferencing an invalid pointer (of which
> the null pointer is one example) is undefined behaviour. This means it is
> perfectly fine for the null pointer to be represented by a bit pattern that
> is also a valid address and for the compiler not to bother generating a check
> that the pointer is not null.
Clever! I worked through this for the benefit of the list:
C11 6.3.2.3p3: If a null pointer constant is converted to a pointer type, the
resulting pointer, called a null pointer, is guaranteed to compare unequal to a
pointer to any object or function.
C11 6.3.2.3p4: Conversion of a null pointer to another pointer type yields a
null pointer of that type. Any two null pointers shall compare equal.
So there must be at least one bit pattern recognizable as a null pointer…
C11 6.5.3.2p1: The operand of the unary & operator shall be either a function
designator, the result of a [] or unary * operator, or an lvalue that
designates an object that is not a bit-field and is not declared with the
'register' storage-class specifier.
C11 6.5.3.2p3: […] Otherwise [when not using [] or *], the result is a pointer
to the object or function designated by its operand.
…and it must not have the same representation as a bit pattern of an object or
function declared in C…
C11 6.5.3.2p4: If an invalid value has been assigned to the pointer, the
behavior of the unary * operator is undefined.
C11 6.3.2.1p1: An lvalue is an expression (with an object type other than
'void') that potentially designates an object; if an lvalue does not designate
an object when it is evaluated, the behavior is undefined.
…but as you say there's nothing stopping a particular compiler from giving the
dereference defined behavior.
However, what this can't do is remove its use as a sentinel value. For example:
C11 7.24.5.1p3: The 'memchr' function returns a pointer to the located
character, or a null pointer if the character does not occur in the object.
So ultimately I see Swift as being just as compatible as C in this case. Both
languages designate a certain bit pattern for use as a placeholder. Swift is a
little more aggressive in keeping you from loading from it, but on such a
platform the standard library could certainly expose a "safely load from this
optional pointer" builtin, which could then perhaps be exposed as a member on
"Optional where Wrapped: _Pointer". (I'm not sure if that's the best way to do
it, but it's an idea.)
As Chris has said previously, both Clang and LLVM themselves have a lot of
assumptions about what can and can't be done with a null pointer, so porting to
any such platform would include a fair amount of work simply extricating that
logic and placing it behind a flag.
Best,
Jordan
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution