<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 30, 2016, at 3:11 , Jeremy Pereira via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><br class=""><blockquote type="cite" class="">On 25 Mar 2016, at 23:00, Brent Royal-Gordon via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""><blockquote type="cite" class="">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.<br class=""></blockquote><br class="">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.<br class=""></blockquote><br class="">This is not true.<br class=""><br class="">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.<br class=""></div></div></blockquote><br class=""></div><div>Clever! I worked through this for the benefit of the list:</div><br class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">C11 6.3.2.3p3: If a null pointer constant is converted to a pointer type, the resulting pointer, called a <i class="">null pointer,</i> is guaranteed to compare unequal to a pointer to any object or function.</div><div class=""><br class=""></div><div class="">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.</div></blockquote><div class=""><br class=""></div><div class="">So there must be at least one bit pattern recognizable as a null pointer…</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">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.</div><div class=""><br class=""></div><div class="">C11 6.5.3.2p3: […] Otherwise [when not using [] or *], the result is a pointer to the object or function designated by its operand.</div></blockquote><div class=""><br class=""></div><div class="">…and it must not have the same representation as a bit pattern of an object or function <i class="">declared in C…</i></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><br class=""></div><div class="">C11 6.5.3.2p4: If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.</div><div class=""><br class=""></div><div class=""><div class="">C11 6.3.2.1p1: An <i class="">lvalue</i> 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.</div></div><div class=""><br class=""></div></blockquote><div class="">…but as you say there's nothing stopping a particular compiler from giving the dereference defined behavior.</div><div class=""><br class=""></div><div class="">However, what this <i class="">can't</i> do is remove its use as a sentinel value. For example:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">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.</div></blockquote><br class=""><div class="">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.)</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Best,</div><div class="">Jordan</div></body></html>