Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

pointers

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.

like image 869
VainMan Avatar asked Sep 16 '21 15:09

VainMan


People also ask

What is an aligned pointer?

Aligned Pointer means that pointer with adjacent memory location that can be accessed by a adding a constant and its multiples. for char a[5] = "12345"; here a is constant pointer if you and the size of char to it every time you can access the next chracter that is, a +sizeofchar will access 2.

What is the alignment of malloc?

new and malloc, by default, align address to 8 bytes (x86) or 16 bytes (x64), which is the optimal for most complex data.

What is the fastest way to align a pointer in C++?

Hands down the fastest way to align a pointer is to use 2's complement math. You need to invert the bits, add one, and mask off the 2 (for 32-bit) or 3 (for 64-bit) least significant bits.

What is the difference between alignas and alignof in C?

The alignas type specifier is a portable, C++ standard way to specify custom alignment of variables and user defined types. The alignof operator is likewise a standard, portable way to obtain the alignment of a specified type or variable. You can use alignas on a class, struct or union, or on individual members.

What is the best way to align data structures in C++?

The C++ standard doesn't specify packing behavior for alignment on boundaries smaller than the compiler default for the target platform, so you still need to use the Microsoft #pragma pack in that case. Use the aligned_storage class for memory allocation of data structures with custom alignments.

How to do 16 bit alignment in embedded C++?

For 16-bit alignment just mask the pointer with 0x1 and add that value. Algorithm works identically in any language but as you can see, Embedded C++ is vastly superior than C in every way shape and form.


Video Answer


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.

like image 78
eerorika Avatar answered Nov 02 '22 13:11

eerorika