> 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

Reply via email to