> unless you assume something not-strictly-portable about `(uintptr_t)p`
What's not strictly portable about it?
padding = -(uintptr_t)p & (align - 1)
The only assumption here is that align is a power of 2, which is guaranteed if it's the result of an alignof().