Why doesn't C++ detect when out of range vector elements are accessed with the [ ] operators by default?

烈酒焚心 提交于 2019-12-18 07:14:50

问题


I understand that arrays are a primitive class and therefore do not have built in methods to detect out of range errors. However, the vector class has the built in function .at() which does detect these errors. By using namespaces, anyone can overload the [ ] symbols to act as the .at() function by throwing an error when a value out of the vector's range is accessed. My question is this: why is this functionality not default in C++?

EDIT: Below is an example in pseudocode (I believe - correct me if needed) of overloading the vector operator [ ]:

Item_Type& operator[](size_t index) { // Verify that the index is legal.
if (index < 0 || index >= num_items) {
   throw std::out_of_range
     ("index to operator[] is out of range");
}
 return the_data[index]
}

I believe this function can be written into a user-defined namespace and is reasonably easy to implement. If this is true, why is it not default?


回答1:


For something that's normally as cheap as [], bounds checking adds a significant overhead.

Consider

int f1(const std::vector<int> & v, std:size_t s) { return v[s]; }

this function translates to just three lines of assembly:

    movq    (%rdi), %rax
    movl    (%rax,%rsi,4), %eax
    ret

Now consider the bounds-checking version using at():

int f2(const std::vector<int> & v, std:size_t s) { return v.at(s); }

This becomes

    movq    (%rdi), %rax
    movq    8(%rdi), %rdx
    subq    %rax, %rdx
    sarq    $2, %rdx
    cmpq    %rdx, %rsi
    jae .L6
    movl    (%rax,%rsi,4), %eax
    ret
.L6:
    pushq   %rax
    movl    $.LC1, %edi
    xorl    %eax, %eax
    call    std::__throw_out_of_range_fmt(char const*, ...)

Even in the normal (non-throwing) code path, that's 8 lines of assembly - almost three times as many.




回答2:


C++ has a principle of only pay for what you use. Therefore unchecked operations definitely have their place; just because you're too lazy to be careful about your bounds doesn't mean I should have to pay a performance penalty.

Historically array [] has been unchecked in both C and C++. Just because languages 10-20 years younger made that a checked operation doesn't mean C++ needs to make such a fundamental backward-incompatible change.



来源:https://stackoverflow.com/questions/30181568/why-doesnt-c-detect-when-out-of-range-vector-elements-are-accessed-with-the

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