<story><title>You Can&apos;t Always Hash Pointers in C</title><url>http://nullprogram.com/blog/2016/05/30/</url></story><parent_chain></parent_chain><comment><author>kazinator</author><text>&amp;gt; &lt;i&gt;In other words, even in a conforming implementation, the same pointer might cast to two different integer values.&lt;/i&gt;&lt;p&gt;If you&amp;#x27;re porting to that type of system, you will be keenly aware of this. The problem can be solved.&lt;p&gt;On the Intel 8086, every address has 4096 ways of referring to it by some combination of segment:offset. A segment is 64 kilobytes wide, and the segment: part of the address is &amp;quot;paragraph&amp;quot; (16 byte block) aligned. 65536&amp;#x2F;16 = 4096. For instance address 0x1234 can be referenced as 0123:0004, or 0122:0014 and so on.&lt;p&gt;However, there &lt;i&gt;is&lt;/i&gt; a unique underlying address.&lt;p&gt;A pointer value can be normalized (using nonportable code, of course) to use, say, the largest possible segment value and the smallest possible offset.  The resulting value can then be hashed.&lt;p&gt;Another way to deal with it on 8086 might be to use a &amp;quot;far&amp;quot; pointer, and calculate its offset from a &amp;quot;far&amp;quot; null pointer:&lt;p&gt;&lt;pre&gt;&lt;code&gt;   (far char *) ptr - (far char *) 0;
&lt;/code&gt;&lt;/pre&gt;
This should produce the physical address as an integer.&lt;p&gt;So that is to say, the concept of hashing an address is sound; only using &amp;quot;pointer&amp;quot; to mean &amp;quot;address&amp;quot; is not maximally portable. An implementation of pointer hashing can be ported to such architectures by some nonportable code, if necessary.&lt;p&gt;If you care about such portability, wrap the &amp;quot;pointer to integer address&amp;quot; logic in a function and implement that function as necessary.</text></comment>
<story><title>You Can&apos;t Always Hash Pointers in C</title><url>http://nullprogram.com/blog/2016/05/30/</url></story><parent_chain></parent_chain><comment><author>gpderetta</author><text>Some motorola 68000 machines did automatically mask out some of the most significant bits of any pointers. This means that two pointers to the same object can have different representation. That did happen in practice as programmers used the highest bits to stuff metadata and relied on the automatic masking. That made things interesting when the platform wanted to increase the address space. And preventing this sort of backward compatiblity issue is the reason why AMD64 will trap if the unused bits of the address space are not all 1 or 0.&lt;p&gt;Bottom line, the pointer to integer conversion should be specified by your platform ABI. Read it, then either refuse to support your program on platforms with insane ABIs or have a fallback path for them.</text></comment>