我正在研究C ++中constexpr的概念。我的理解是constexpr在编译时得到评估。在here中,我找到了一个示例,其中包含以下代码段。
int z[30];
constexpr auto e2 = &z[20] - &z[3];
他们正在计算编译时地址之间的差。当我们不知道编译时地址的实际值时,如何在编译时求值?
答案 0 :(得分:10)
constexpr auto e2 = &z[20] - &z[3];
只是计算第三和第20元素之间的偏移量。因此,无需了解地址。
另一方面,以下示例不起作用,因为z[20]
和t
的地址是在运行时求值的。
int z[30];
int t;
constexpr auto e2 = &z[20] - &t;
Passer By
指出,根据标准(7.6.6 Additive operators,最后一句),这是未定义的行为:
除非两个指针都指向同一数组对象的元素,否则 在数组对象的最后一个元素之后,行为是不确定的。
答案 1 :(得分:2)
编译器不需要知道地址的实际值。它采用简单的指针算法。由于z是整数数组,因此在数组中减去两个整数地址将得出下标之间的差。
所以
constexpr auto e2 = &z[20] - &z[3];
将导致将值17分配给e2。
答案 2 :(得分:0)
然后,编译器将通过汇编程序生成机器代码和变量地址。地址可以是绝对地址,也可以是可重定位的地址。然后,当加载程序将其放入内存段时或在内存中时,必须固定这些地址。 constexpr所说的全部是,您可以在编译时评估这些事情,可以的。有一个地址。有一个价值。机器代码或可执行代码将在后台使用操作系统基于新偏移量的地址从字面上进行更新。程序员不再担心16位实际系统上的绝对寻址。程序员只需要知道该过程是如何工作的即可。
数组在内存中是连续的,因此即使相对寻址,它们之间的距离也将是N个字节...。一个非常常数的表达式确实大声笑