Is it safe to access the value of an array in a loop stop state?

To improve the performance of my clique-partitioning program, which uses ordered arrays, I included access to the element of the array that I am looping in to stop my for loop.

 int myValue = 13; for (int i=0; array[i] < myValue; i++) { //performing operations on the array } 

This is clearly unsafe, as it may be that my array contains only myValue values, so I tried this

 int myValue = 13; for (int i=0; i < array.size() && array[i] < myValue; i++) { //performing operations on the array } 

Everything seems to be going well in this implementation, but if I switch the conditions, I will fall into the same problem of the first example.

 int myValue = 13; for (int i=0; array[i] < myValue && i < array.size(); i++) { //performing operations on the array } 

So, I realized that this is clearly due to the way the compiler sets the order of the two conditions, because in the latter case, even if I ask to enter a loop only if i not larger than the size from the array, I first read the value, which may be outside the bounds array.

My question is: is it always safe to do what I did in the second implementation, or can the compiler sometimes switch my control conditions, resulting in unsafe code?

Thanks.

+4
source share
2 answers

The && operator (logical and) always has short circuits, if possible. Your second example is safe.

Note. This applies only to primitive types, and not to those that overload logical operators.

Since no self-respecting C++ answer would be executed without a standard quote :

5.14.1 (logical AND) & & groups of operators from left to right. The operands are converted in context to the bool type (section 4). The result is true if both operands are true and false otherwise. Unlike && & guarantees from left to right evaluation: the second operand is not evaluated if the first operand is false.

5.14.2 (logical OR) || groups of operators from left to right. The operands are converted to context in bool (section 4). This returns true if any of its operands is true, and false otherwise. Unlike |, || guarantees from left to right; in addition, the second operand is not evaluated if the first operand is true.

+7
source

I would not do a single example. Do it:

 for (int i=0; i < array.size(); i++) { if (array[i] >= myValue) { break; } // do stuff } 

Thus, you have no confusion or insecurity. It has the same speed as in other examples, but is much simpler for subsequent debugging.

0
source

Source: https://habr.com/ru/post/1443343/


All Articles