Hi Paul, > > "Prefer intptr_t for internal representations of pointers" > > > > I disagree with this advice. uintptr_t ought to be used for representing the > > address of a pointer. > > It depends on the application. For example, with two char * pointers P and Q > into an array, it can be helpful that P - Q yields the same integer as > ((intptr_t) P - (intptr_t) Q), assuming the usual representation.
Suppose that we have an array that extends from 0x7fff8000 to 0x80003fff - this can happen! look at the address range maps -, and - either P = 0x7fffc000 and Q = 0x80003000 then ((intptr_t) P - (intptr_t) Q) causes a signed integer overflow (value > INTPTR_MAX), - or vice versa: P = 0x80003000 and Q = 0x7fffc000 then ((intptr_t) P - (intptr_t) Q) causes a signed integer overflow (value < INTPTR_MIN). So, with an undefined-behaviour sanitizer enabled, the program will crash. > That's not true for uintptr_t. With uintptr_t, the program will not crash for an address difference computation. The expression (intptr_t)((uintptr_t) P - (uintptr_t) Q) will always return the expected value. (Here we assume that no array consumes more than half of the address range, a constraint that is also your justification for using ptrdiff_t.) > In practice, Emacs uses uintptr_t quite a bit for things like hashes and tags; > but it uses intptr_t a bit more, so the advice seems reasonable for Emacs. No, the advice is bad, even for Emacs. Bruno