【发布时间】:2020-09-23 12:19:03
【问题描述】:
我正在使用 constexpr 方法实现一个 Array 类。在我的设计中,我允许迭代器超过 end(),因为我没有做:while (it != arr.end()),而是通过在内部比较两个原始指针来做:while (arr.finished(it)) .它适用于非 constexpr 数组实例,但不适用于 constexpr 实例,因为以下问题:
#include <array>
int main()
{
static constexpr std::array<int, 3> arr{};
constexpr const int* ptr = &arr[0];
constexpr const int* ptr2 = (const int*)ptr + 4;// error
return 0;
}
我收到了消息:
array subscript value 4 is outside the bounds of array type _Type {aka const int [3]}|
Windows 10 和 gcc10.1.0 位于 C:\cygwin64\usr\local\bin
我什至没有取消引用指针,所以我对编译器的“小心”感到愤怒。
我的问题是:
我可以做些什么来编译这段代码并保持我的设计选择有越界迭代器? (不仅仅是编译器已经允许的最后一个结尾)。我可以用 gcc 禁用越界错误吗?
【问题讨论】:
-
当你使用
constexpr时,编译器有义务检查UB。它不能忽视它。由于数组边界外的指针算术是UB,编译器必须报错。 -
超出
end()是标准的UB。 -
constexpr能够检测 UB 并将它们作为错误线程。所以你的代码有 UB 应该被修复。 -
@Evg 感谢 cmets,有什么原因吗?
-
@Cevik 看看this answer:一些架构有专门的寄存器来保存指针。将未映射地址的值放入这样的寄存器是允许崩溃的。
标签: c++ arrays pointers constexpr