Although I'm not entirely sure what you mean by "type safe"1,2 in this context, you can use const
with the appropriate ...ptr_t
type to ensure that the (constant) value you provide is valid for the pointer.
Take the following code, for example:
#include <iostream>
#include <cstdint>
// I added an extra zero to your constant - now it's too big for a 32-bit pointer
constexpr uintptr_t reg_a_addr = 0x800000000; // uintptr_t is platform-specific
uint32_t* const ptr_reg_a = reinterpret_cast<uint32_t* const>(reg_a_addr);
// ^ Note that "const unit32_t* ptr_reg_a ..." declares a pointer to a constant;
// the version I have given defines a constant pointer to (potentially) writable memory.
int main()
{
std::cout << ptr_reg_a << "\n";
return 0;
}
When targeting the x64 platform with MSVC, this compiles without warning and produces the expected output:
0000000800000000
However, when targeting the x86 (32 bit) platform, the compiler will issue warnings that the value is too big:
warning C4305: 'initializing': truncation from '__int64' to 'const
uintptr_t'
warning C4309: 'initializing': truncation of constant
value
And, indeed, the output will be the truncated value:
00000000
As to whether or not it is practical – well, it compiles but trying to use a constexpr
with reinterpret_cast
doesn't, so I guess it is!
Note that the clang-cl compiler in Visual Studio 2022 (when targeting 32 bits) gives an 'equivalent' warning for the constant being too big:
warning : implicit conversion from 'long long' to 'const uintptr_t'
(aka 'const unsigned int') changes value from 34359738368 to 0
[-Wconstant-conversion]
1 Maybe, by "type safe," you mean that reassigning a new value to that pointer will be prevented at compile time … in which case: Yes, it is type safe, as code like the following will not compile:
uint32_t q = 42;
ptr_reg_a = &q;
error : cannot assign to variable 'ptr_reg_a' with const-qualified
type 'uint32_t *const' (aka 'unsigned int *const')
2 If you are asking whether or not using const
rather than constexpr
will make such a pointer any less strictly typed, then: No, it won't. However, (IIRC) the C++ Standard does impose stricter requirements for diagnostics on potential misuse of constexpr
values … but many (if not most) mainstream compilers will, if warnings are fully enabled, provide suitable diagnostics for cases of (say) violation of strict aliasing rules, or other usage of such a pointer that exhibits undefined behaviour.