在 constexpr 中将 'void*' 转换为 'unsigned int'
convert `void*` to `unsigned int` in constexpr
一个人不能在 constexpr 中做一个reinterpret_cast<unsigned int>(void*)
,所以我正在尝试类似的东西;
constexpr bool is_null(void* ptr)
{
return ptr == nullptr;
}
constexpr unsigned int get_id(void* ptr)
{
return is_null(ptr) ? 0 : 1 + get_id(static_cast<char*>(ptr) - 1);
}
但是我在编译时收到一个错误,关于 ptr == nullptr 不是 constexpr,但仅在递归调用中,而不是如果我删除它。那么,如果可能的话,如何在编译时将void*
转换为unsigned int
呢?
在编译时,地址常量表达式由"符号 + 加法"表示形式跟踪,例如:
int x[5];
constexpr int* p = x + 3 - 1;
假设int
是 4 个字节,p
是 symbol=x,addend=2*4=8 个字节。 p = x+8。
因此,您只能对具有相同符号的地址常量表达式执行指针操作,因为在转换过程中不知道它们的最终相对地址是什么。 此外,加法可能不会超出对象,主要是为了安全起见,但也因为您可能最终为 null。 例如,假设 x 在地址 4000 十进制处分配。 然后,x-1000 将是一个空指针表达式,但直到链接时才知道。
标准中的规则旨在支持这种表示。 可以对它们执行的常量操作反映了在此表示形式下可用的信息。
另请注意,非静态存储持续时间变量的绝对地址在链接时甚至未知,自动存储持续时间对象的堆栈相对地址与每个函数调用不同,动态存储持续时间对象在运行时确定堆地址。
相关文章:
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 定义 uint= "unsigned int" 没有像我在 Visual Studio 中使用 nvcc 时预期的那样应用
- 对 '(const Y) (int&, std::mersenne_twister_engine<long unsigned int,
- 错误:'class std::unique_ptr<std::set<long unsigned int> >'没有名为 'size' 的成员
- 正确语法,用于统一初始化名称中带有空格的类型的临时,如unsigned int
- 按值对 std::unordered_map<std:::string, std::atomic<unsigned int>> 进行排序
- 编译Qt项目给出了对运算符delete(void*,unsigned int)的未定义引用
- 错误:无法将'uint8* {aka unsigned int*}'转换为"常量emxArray_uint8_T*"?
- 没有匹配函数来调用"std::basic_ofstream<char>::write(std::string*, long long unsigned int)"
- 初始化unsigned int至0
- 为什么"unsigned int" + "unsigned int"返回"unsigned int"?
- 对 'WindowProc(HWND__*, unsigned int, unsigned int, long)@16' 的未定义引用
- {app.exe!_com_error::'vector delete destructor'(unsigned int)}
- flann/util/serialization.h class std::unordered_map<unsigned int, std::vector<unsigned int>
- 从'byte* {aka unsigned char*}'到'dword {aka长unsigned int}'失去精度
- unsigned int/signed int/long-long:无法解释的输出
- 对"uint32_t"的暧昧呼唤"long unsigned int"
- 带有unsigned int参数的C++函数在使用negative调用它时会得到奇怪的结果
- 从'uint64_t'转换为'unsigned int'