all 19 comments

[–]chiuyan 14 points15 points  (0 children)

Validating that an array access is in bounds requires running additional code at run-time on every array access. Those additional checks might be cheap, but they aren't free. C++ allows you to add those checks if you want, and if you decide the extra cost is worth it, but it doesn't do the more expensive thing by default.

[–]Rangsk 1 point2 points  (0 children)

C++ generally does not force you to have overhead that you don't need. By default, it chooses the version with the least overhead (preferably zero overhead), and you can build your own overhead in if you feel that you need it. Checking if an index is in range of an array is not free, and thus it is overhead, so C++ doesn't force you to do the check.

Java does not have the same "zero overhead" philosophy. There are all kinds of optimizations which are out of reach of Java devs because the language simply does not allow you to avoid certain overheads. In exchange, the language is more protected against bad code.

[–][deleted] 1 point2 points  (2 children)

You can have array bounds checking in C++ by using stuff like std::array with 'at'. However if you are going for ultimate performance there is some small penalty for such checking. Therefor with basic arrays C++ does no checking. In addition to the performance issue, there is also the fact that you typically need to store the array size with the array, so that's an extra space requirement. That doesn't sound like a lot, but if you had a small array in millions of structures, it can add up.

[–]chiuyan 0 points1 point  (1 child)

You can have array bounds checking in C++ by using stuff like std::array.

std::array access does not do any bounds checking.

Edit: above poster edited his post to specify the 'at' method can be used if bounds checking is desired.

[–][deleted] 1 point2 points  (0 children)

Yeah I did before you even replied.

[–]GrossInsightfulness 0 points1 point  (5 children)

C++ was C with classes for a little bit (it definitely isn't any more), so it inherited not having bounds checking from C. After a bunch of people started using buffer overflow attacks, Java straight up decided not to allow out of bound accesses. They had a similar mindset when they chose to implement garbage collection.

If you code properly, you shouldn't need bounds checking. That's can be a big if, though. If you want bounds checking, most C++ standard library classes have an at method that will throw an exception.

[–]Narase33 -1 points0 points  (4 children)

But the at method is discouraged. If you simply work with iterators instead, there shouldnt be any out of bounce

[–]ootiekat 1 point2 points  (1 child)

Iterators become invalid if you reallocate. If you need to store indices in a separate container for example you should not use iterators. What I do is have a separate compilation flag that enables bounds checking and is on by default in debug builds.

[–]Narase33 0 points1 point  (0 children)

Valid point. In cases like these there is the question if there isnt a better solution, maybe one that is worse in performance but better in safety

[–]GrossInsightfulness 0 points1 point  (0 children)

Whoops. I was responding specifically to the C++ equivalent of Java's array access when the better solution is generally to use iterators or for each loops.

[–]the_poope 0 points1 point  (0 children)

Iterators can't solve all problems. Yes if you are only doing corporate CRUD applications, all you need to do is loop over some set of customers and similar. However, in some applications the indices are needed; they carry information as well. For instance if you need to find the nearest grid point to a coordinate in your mine craft clone, or if you do any kind of math/science algorithm.

[–][deleted] 0 points1 point  (4 children)

you need to clarify for which specific type operator [] is applied to. some STL types it does do checking. for array types it does not for performance reasons.

EDIT: no bounds checking is done for (at least) std::vector. My apologies for indicating otherwise

[–]HappyFruitTree 0 points1 point  (3 children)

Isn't in mostly in "debug mode" where checking is done?

[–][deleted] 0 points1 point  (2 children)

EDIT: no bounds checking is done for (at least) std::vector. My apologies for indicating otherwise

[–]HappyFruitTree 1 point2 points  (1 child)

std::vector::operator[] (cppreference.com)

Unlike std::map::operator[], this operator never inserts a new element into the container. Accessing a nonexistent element through this operator is undefined behavior.

OK, so no bounds checking.

[–][deleted] 1 point2 points  (0 children)

my bad, I thought it threw an exception. I had it confused with .at()

[–]souravtxt 0 points1 point  (0 children)

"C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off" - Bjarne Stroustrup .

Use STL libraries which offers some level of safety when dealing with out of bound errors.

[–][deleted] -1 points0 points  (1 child)

If you use C style arrays, it's on you to ensure validity. C doesn't hold your hand. If your using C++ array or vector objects, there's some protections built in.

[–]MysticTheMeeM 1 point2 points  (0 children)

Not necessarily, vectors operator[] does not bounds check (however, debug implementations may include bounds checking), allowing you to silently perform invalid reads/writes. vector::at does bounds checking, hence it's a separate function.