c++ - 在 constexpr 中将 `void*` 转换为 `unsigned int`

标签 c++ c++11 constexpr

一个人不能做 reinterpret_cast<unsigned int>(void*)在一个 constexpr 中,所以我正在尝试类似的东西;

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。

所以你只能对具有相同符号的地址常量表达式进行指针操作,因为在翻译过程中不知道它们的最终相对地址是什么。此外,加数可能不会超出对象,主要是为了安全,但也因为您可能最终为空。例如,假设 x 分配在十进制地址 4000 处。 x-1000 将是一个空指针表达式,但直到链接时才知道。

标准中的规则旨在支持这种表示。可以对它们执行的常量操作反射(reflect)了在这种表示下可用的信息。

另请注意,非静态存储持续时间变量的绝对地址在链接时甚至是未知的,自动存储持续时间对象具有随每个函数调用而不同的堆栈相对地址,而动态存储持续时间对象具有堆地址在运行时决定。

关于c++ - 在 constexpr 中将 `void*` 转换为 `unsigned int`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18625151/

相关文章:

c++ - 为什么不能将 static constexpr 成员变量传递给函数?

c++ - constexpr : literal class type copy behavior

c++ - 如何将L值传递给std::make_pair

c++ - boost::asio 中的未经请求的消息使应用程序崩溃,没有 SSL 它工作正常,为什么?

c++ - 如何将 GSL 与 C++11 和新的 STL 一起使用?

c++ - C++11 将改变哪些良好的编程实践?

c++ - 使用 C++17 的 Constexpr 查找数组

c++ - C++ 中的 new 返回 (void *) 吗?

c++ - QT QtConcurrent 以重载类函数运行

c++ - 从 constexpr 数组创建可变参数模板