为什么即使使用constexpr索引,编译器也允许越界数组访问? [英] Why does compiler allow out-of-bounds array access even with constexpr index?

查看:90
本文介绍了为什么即使使用constexpr索引,编译器也允许越界数组访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,如果我们有一个std::array,并且使用constexpr实例化了一个超出范围的元素,则编译器将不会报告错误:

For example if we have an std::array and we instantiate an element that is out of bound using constexpr the compiler wouldn't report error:

constexpr int EvaluateSpecialArrayIndex(int a)
{ return a * sizeof(int); }

array<int, 5> arr;

cout << arr[98] << endl; //compiles fine

cout << arr[EvaluateSpecialArrayIndex(4)] << endl; //the same as above

我们不能以某种方式限制这一点吗?

Can't we restrict this somehow?

推荐答案

为确保在编译时对constexpr函数进行求值,必须通过使它们的结果为constexpr来强制使用它们.例如:

To ensure that constexpr functions are evaluated at compile time, you must force them to be by making their result constexpr. For example:

#include <array>

int
main()
{
    constexpr std::array<int, 5> arr{1, 2, 3, 4, 5};
    int i = arr[6];  // run time error
}

但是:

#include <array>

int
main()
{
    constexpr std::array<int, 5> arr{1, 2, 3, 4, 5};
    constexpr int i = arr[6];  // compile time error
}

不幸的是,要使其真正起作用,std::array必须符合C ++ 14规范,而不是C ++ 11规范.由于C ++ 11规范未将std::array::operator[]const重载标记为constexpr.

Unfortunately, for this to actually work, std::array must conform to the C++14 specification, not the C++11 specification. As the C++11 specification does not mark the const overload of std::array::operator[] with constexpr.

所以在C ++ 11中,您很不走运.在C ++ 14中,您可以使其工作,但前提是同时声明array和调用索引运算符的结果都声明为constexpr.

So in C++11 you're out of luck. In C++14, you can make it work, but only if both the array and the result of calling the index operator are declared constexpr.

说明

用于数组索引的C ++ 11规范为:

The C++11 specification for array indexing reads:

                reference operator[](size_type n);
          const_reference operator[](size_type n) const;

对于数组索引的C ++ 14规范为:

And the C++14 specification for array indexing reads:

                reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;

constexpr已添加到C ++ 14的const重载中.

I.e. constexpr was added to the const overload for C++14.

更新

对于数组索引的C ++ 17规范为:

And the C++17 specification for array indexing reads:

constexpr       reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;

该循环现已完成.可以在编译时计算Universe. ;-)

The cycle is now complete. The universe can be computed at compile-time. ;-)

这篇关于为什么即使使用constexpr索引,编译器也允许越界数组访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆