简体   繁体   中英

Static bound checking for array in C++

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM