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



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

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的bit_cast也明确地不是constexpr

这一点很重要,因为运行时事物的地址与其编译时地址不同。事实上,构建系统中处理常量求值的部分(又名:编译器(与构建系统中负责为事物分配地址的部分(别名:链接器(不同。由于编译器看不到未来,它无法计算编译时对象的运行时地址

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

最新更新