获取在编译时转换为算术类型的对象的地址

Get address of object cast to arithmetic type at compile time

我正在尝试在 C++ 中实现 x86 页面 tables/page 目录,我希望能够在编译时构建这些目录。为了做到这一点,我需要能够在编译时获取静态 constexpr 页面 table 对象的地址,转换为算术类型,这样我就可以使用它们来构造静态 constexpr 页面目录条目,如下所示:

struct PageTable {
  /* ... */
};

struct PageDirectory {
  constexpr PageDirectory(std::initializer_list<uint32_t> entries)
  { /* ... */ }

  /* ... */
};

static constexpr PageTable pt { /* ... */ };

static constexpr PageDirectory pd {
  reinterpret_cast<uint32_t>(&pt) | WRITE | PRESENT,

  /* ... */
};

这不起作用,因为 reinterpret_cast 不能在常量表达式中使用。有没有其他方法我可以实现这个或类似的东西?

在编译时,通常不允许您进行低级欺骗,例如访问地址的数值。如果源对象是(或包含)指针,即使 C++20's bit_cast 也明确不是 constexpr

这很重要,因为事物在运行时的地址与其编译时地址不同。实际上,处理持续评估的构建系统部分(又名:编译器)与处理为事物分配地址的构建系统部分(又名:链接器)不同。由于编译器看不到未来,因此无法计算编译时对象的运行时地址。

当然,还有一个事实是链接器 本身 可能不知道该地址是什么,因为现代 OS 通常将可执行文件分配给任意虚拟每次加载可执行文件时都不同的地址。虽然 linker/OS 不必这样做,但该语言在设计时确实需要考虑到这一点。也就是说,它不能做一些使这些事情不可能或不可行的事情。