Static bound checking for array in C++

旧街凉风 提交于 2019-12-22 09:49:26

问题


I'm in need for some guidance regarding a question from a programming languages course I'm taking.

We need to come up with a way to implement an array class in C++, so that accessing it's element is statically checked for overflow. We are not to use C++11 (static assertion) nor any other black-box solution - this is a theoretical question, not something I need for coding purposes.

we did get a strong hint in the lecture slides :

" it is impossible to detect overflow of array indices when indices are of type integer – not if the type of the indices corresponds to the array size (which must be part of the type of the array). "

I thought about using fixed-length (array size) string for indices, but other than thinking about the option I really did not get much :(.

Clarification: OK, this has got some confused replies to it, probably because I was unclear - So I will re-emphasize:

  1. "Statically" means "at compile time". The compiler should alert the user of the overflow (Warning/Error..). Not runtime!
  2. Read the "hint" given to us - it's to be used. specifically, the program may NOT check for bounds! specifically the at() method of arrays in c++ is not to be used or emulated.

In light of all this what I am thinking they want is some sort of transformation int->(Indices type) that somehow fails or computes wrong values for these indices in case the array is overflowed.

Hope that is clearer now. Thank you's


回答1:


Maybe he intends for you to index the array based on a type where the value is part of the type, such as std::integral_constant<int, value>. Using this, the size can be checked at compile time. However, without static_assert, it's hard to think of simple ways to assert that one constant is smaller than another.

Here, I use the trick of comparing if the index is less than the size, converting that to an integer (0 if it's out of bounds, or 1 otherwise), multiplying that by two and subtracting one, giving either (-1 for out of bounds, or 1 for valid), and then making an array of that size. This causes a compilation error if the index is out of bounds, and is optimized out if the index is valid.

#include <type_traits>

template<class T, int count>
struct array {
    array() : data() {}

    template<int N>
    T& operator[](std::integral_constant<int,N> index) {
        //compiler error if index is too small
        char index_is_too_large[(N<count)*2-1]={}; 
        index_is_too_large[0] = index_is_too_large[0]; 
        //second line makes the compiler ignore warnings

        return data[N];
    }
private:
    T data[count];
};

#include <iostream>
int main() {
    array<float, 3> thingy;

    std::integral_constant<int, 2> index2;
    std::cout << thingy[index2] << '\n';

    std::integral_constant<int, 3> index3;
    std::cout << thingy[index3] << '\n'; //COMPILER ERROR ON THIS LINE
}

This seems quite advanced for the restrictions placed on you, I think it's more likely you misunderstood your professor somewhere along the line.



来源:https://stackoverflow.com/questions/17308104/static-bound-checking-for-array-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!