我明白为什么这不能编译:
int main() {
constexpr int i = 0;
constexpr const int* ptr = &i;
}
本地变量地址在运行时评估(尽管可以在本例中解析)。
编译:
constexpr int i = 0;
int main() {
constexpr const int* r = &i;
}
这也可以编译:
int main() {
static constexpr int i = 0;
constexpr const int* r = &i;
}
据我了解,这意味着解析静态变量的地址被视为编译时功能。规范强制要求这种行为吗?
第二个和第三个程序是有效的标准 C++。它不仅仅是一个特定的编译器允许它。任何符合标准的编译器都必须编译它。
常量表达式的结果可以是或包含指向具有静态存储持续时间的对象的指针。
但这并不意味着这些对象的地址作为它们的数值可以在编译时使用。获得这些数值的唯一方法是使用
reinterpret_cast
,这在编译时是被禁止的。
因此,编译器只需跟踪存在哪些静态存储持续时间对象以及给定的常量表达式结果是否象征性地指向这些对象中的任何一个,而无需担心地址值。地址的实际值可以稍后由链接器照常填写。