简体   繁体   中英

constexpr of pointer to fixed address

I have code like this:

constexpr int *p = (int*)0x12345678;

but the compiler (rightfully) says:

foo.cc:1:20: error: ‘reinterpret_cast’ from integer to pointer
    1 | constexpr int *p = (int*)0x12345678;
      |                    ^~~~~~~~~~~~~~~~

Is there any equivalent code or way to mark this instance of a cast to be acceptable as constexpr?

Note: In the embedded / micro-controller world having memory mapped device registers is really common but because of this one can't use constexpr for any of the code involved with them.

PS: A solution requiring gcc or clang is fine. Doesn't need to be portable.

This non-portable method appears to work using g++ 11 and GNU ld, even allowing the pointer to be used as a template argument. (clang++ does not allow it as a template argument.)

A pointer-type template argument must point at a named variable with external linkage, so I introduce a variable for the actual value, and get the linker rather than compiler to provide that variable's symbol name as a specific address.

#include <cstdio>

// Provide command-line argument -Wl,--defsym=p_var=0x12345678
extern volatile int p_var;
constexpr volatile int* p = &p_var;
constexpr volatile int* p2 = p+1;
constexpr volatile int* p3 = p2-1;

template <volatile int* P> void print_addr() {
    std::printf("%p\n", const_cast<void*>(static_cast<volatile void*>(P)));
}

// After linking, the code contains constant 0x1234567c and no add instruction.
volatile int* get_p2() { return p2; }

int main() {
    print_addr<p>();
    // print_addr<p2>();  ERROR: invalid template argument
    print_addr<p3>();
}

Some of the pointer arithmetic is actually happening at link time, not compile time, but g++ apparently doesn't mind for the purposes of C++ language requirements.

Try this code on godbolt.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM