>>32This makes a O(1) pointer synthesis difficult for implementations where wordsize < ptrsize
I don't think you know how big-O notation works and you probably shouldn't use it.
In addition, nowhere in the C Standard it claims that pointer size should be the same as "word size" (whatever that is, it's not mentioned in the Standard at all). There are many architectures where it's not true, for example all 8-bit processors and many 16-bit processors, most notably the Intel x86 family up to and including 80286.
Furthermore, the standard doesn't demand that the representation of a pointer as an uintptr_t should make any sense wrt its internal structure. You are guaranteed that converting that exact value to a pointer would produce the original pointer, the actual bits of the representation could be shuffled and xored with a random constant for all you know.
Furthermore, even if you could depend on that, nothing in the standard guarantees that sizeof(int) > 1 so you have those extra unused bits due to alignment. For example, if your target architecture only supported aligned loads and stores, its native indirect addressing instructions could enumerate addresses in words, not in bytes. And even if your implementation wanted to avoid wasting space and allow storing several chars in a word, it could use native address representation for word and larger pointers and some special representation for char pointers (see the previous point).
All that was said with an assumption that we are talking about translating
Standard conforming C software.
in turn inconveniencing translation into any language where pointer-to-integer-to-pointer casting isn't allowed by the target language's specification.
However as someone has already pointed out, for that particular purpose you can just store objects in arrays and use their indices as addresses, no problem. Accessing subobjects would be trickier.