Unfortunately, in C99 it seems pretty tough to guarantee alignment of any sort in a way which would be portable across any C implementation conforming to C99. Why? Because a pointer is not guaranteed to be the "byte address" one might imagine with a flat memory model. Neither is the representation of uintptr_t so guaranteed, which itself is an optional type anyway.
We might know of some implementations which use a representation for void * (and by definition, also char *) which is a simple byte address, but by C99 it is opaque to us, the programmers. An implementation might represent a pointer by a set {segment, offset} where offset could have who-knows-what alignment "in reality." Why, a pointer could even be some form of hash table lookup value, or even a linked-list lookup value. It could encode bounds information.
In a recent C1X draft for a C Standard, we see the _Alignas keyword. That might help a bit.
The only guarantee C99 gives us is that the memory allocation functions will return a pointer suitable for assignment to a pointer pointing at any object type. Since we cannot specify the alignment of objects, we cannot implement our own allocation functions with responsibility for alignment in a well-defined, portable manner.
It would be good to be wrong about this claim.