What treatment can a pointer undergo and still be valid?
<p>Which of the following ways of treating and trying to recover a C pointer, is guaranteed to be valid?</p>

<p>1) Cast to void pointer and back</p>

<pre><code>int f(int *a) {
    void *b = a;
    a = b;
    return *a;
}
</code></pre>

<p>2) Cast to appropriately sized integer and back</p>

<pre><code>int f(int *a) {
    uintptr_t b = a;
    a = (int *)b;
    return *a;
}
</code></pre>

<p>3) A couple of trivial integer operations</p>

<pre><code>int f(int *a) {
    uintptr_t b = a;
    b += 99;
    b -= 99;
    a = (int *)b;
    return *a;
}
</code></pre>

<p>4) Integer operations nontrivial enough to obscure provenance, but which will nonetheless leave the value unchanged</p>

<pre><code>int f(int *a) {
    uintptr_t b = a;
    char s[32];
    // assume %lu is suitable
    sprintf(s, "%lu", b);
    b = strtoul(s);
    a = (int *)b;
    return *a;
}
</code></pre>

<p>5) More indirect integer operations that will leave the value unchanged</p>

<pre><code>int f(int *a) {
    uintptr_t b = a;
    for (uintptr_t i = 0;; i++)
        if (i == b) {
            a = (int *)i;
            return *a;
        }
}
</code></pre>

<p>Obviously case 1 is valid, and case 2 surely must be also. On the other hand, I came across a post by Chris Lattner - which I unfortunately can't find now - saying something similar to case 5 is <em>not</em> valid, that the standard licenses the compiler to just compile it to an infinite loop. Yet each case looks like an unobjectionable extension of the previous one.</p>

<p>Where is the line drawn between a valid case and an invalid one?</p>

<p>Added based on discussion in comments: while I still can't find the post that inspired case 5, I don't remember what type of pointer was involved; in particular, it might have been a function pointer, which might be why that case demonstrated invalid code whereas my case 5 is valid code.</p>

<p>Second addition: okay, here's another source that says there is a problem, and this one I do have a link to. <a href="https://www.cl.cam.ac.uk/~pes20/cerberus/notes30.pdf" rel="noreferrer">https://www.cl.cam.ac.uk/~pes20/cerberus/notes30.pdf</a> - the discussion about pointer provenance - says, and backs up with evidence, that no, if the compiler loses track of where a pointer came from, it's undefined behavior.</p>