Search code examples
c++gcccudamemory-alignmentnvcc

How can I indicate to the compiler that a pointer parameter is aligned?


I'm writing the spectacular function:

void foo(void* a) {
    if (check_something_at_runtime_only()) {
        int* as_ints { a };
        // do things with as_ints
    }
    else {
        char* as_chars { a };
        // do things with as_chars
    }
}

Suppose we know that some work with as_ints would benefit from it being better-aligned; e.g. if the memory transaction size on my platform is N bytes, then I can read the first N/sizeof(int) elements with a single machine instruction (ignoring SIMD/vectorization here) - provided a is N-byte-aligned.

Now, I could indicate alignment by having foo always take an int * - at least on platforms for which larger types can only be read from aligned addresses - but I would rather keep the type void *, since it doesn't have to be an array of ints, really.

I would have liked to be able to write something like

void foo(alignas(sizeof(int)) void* a) { ... }

but, apparently, alignas doesn't apply to pointers, so I can't.

Is there another way to guarantee to the compiler than the argument address will be aligned?

Notes:

  • I'm interested both in what the C++ standard (any version) allows, and in compiler-specific extensions in GCC, clang and NVCC (the CUDA compiler).

Solution

  • In C++20 you can use std::assume_aligned:

    #include <memory>
    
    int *as_ints = std::assume_aligned<sizeof(int)>(a);