Is there a portable (C++ standard) way to compute the previous aligned pointer?

Viewed 313

Given alignas(N) char buffer[N]; and a char* p between [&buffer[0], &buffer[N-1]], can I obtain a pointer to buffer[0] by using p and N?

char* previous_aligned_pointer(char* ptr, size_t align) {
   // how?
}

int main() {
  constexpr int N = 32;
  alignas(N) char buffer[N];
  assert(previous_aligned_pointer(&buffer[rand() % N], N) == &buffer[0]);
}

I'd like to do it in portable C++ (if possible), so something like casting a pointer to uintptr_t and then performing arithmetic on it may not be used.

1 Answers

There is a standard library function to get the next aligned pointer. It's called std::align. You could then subtract the alignment to get the previous one.

In general that may do pointer arithmetic beyond the buffer in which case the subtraction would technically be UB. If that's a concern, then you could avoid the UB if you can allocate extra space in the buffer such that the next aligned pointer is always within the buffer.

Only other way is to implement it yourself which would have to rely on conversion to integer type which relies on implementation dependent unguaranteed behaviour. In conclusion: No, I don't think there's a general strictly standard conforming solution.


However, for your example case, there's no problem. The next aligned address is pointer past the end, so it's fine to subtract N to get the address to beginning of the buffer.

Related