Lazy evaluation [c++]

Started by
7 comments, last by Xai 18 years ago
I just want to be sure of this... we can trust that this is always safe, correct?

if( i < ARRAY_SIZE && array == 'z' )
{
   ...
}

(That is, 'array' shouldn't have an out-of-bounds error, ever)
--== discman1028 ==--
Advertisement
C and C++ are 100% guaranteed to perform short-circuit left-to-right evaluation ... so you are safe
...assuming i is non-negative and ARRAY_SIZE is no greater than the real size of the array.

Σnigma
Quote:Original post by Xai
C and C++ are 100% guaranteed to perform short-circuit left-to-right evaluation ... so you are safe


Is that stipulated by the standard?

GCS584
Quote:Original post by gcs584
Quote:Original post by Xai
C and C++ are 100% guaranteed to perform short-circuit left-to-right evaluation ... so you are safe


Is that stipulated by the standard?

GCS584


Yes, even though I can't quote it. =)
Actually I need to add another condition: "and provided there is not an overloaded operator&& compatible with the types resulting from the expressions i < ARRAY_SIZE and array == 'z'".

The built in operator&& is guaranteed by the standard to provide left-to-right evaluation with the right hand side not being evaluated if the left hand side evaluates to true. Overloaded versions of operator&& are functions and therefore do not provide guaranteed left-to-right evaluation.
Quote:C++ Standard, Final Draft, Section 5.14, Paragraph 1
The && operator groups left-to-right. The operands are both implicitly converted to type bool (4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
Quote:C++ Standard, Final Draft, Section 5, Paragraph 2
Operators can be overloaded, that is, given meaning when applied to expressions of class type (9) or enumeration type (7.2). Uses of overloaded operators are transformed into function calls as described in 13.5. Overloaded operators obey the rules for syntax specified in this clause, but the requirements of operand type, lvalue, and evaluation order are replaced by the rules for function call. Relations between operators, such as ++a meaning a+=1, are not guaranteed for overloaded operators (13.5), and are not guaranteed for
operands of type bool. —end note]

Σnigma

Thanks for the clarification,

GCS584
If array is an actual array (and not a pointer), then:
if (i >= 0 && i < sizeof(array)/sizeof(array[0]) && array=='z') {}

works nicely.

You could also try:
bool bounded(int min, int value, int max) {  return value >= min && value < max;}template<typename T>bool InBounds(std::vector<T> const& v, int i) {  return bounded(0, i, v.size());}template<typename A, int n>bool InBounds(A const& a[n], int i) {  return bounded(0, i, n);}


And then:
if (InBounds(array, i) && array == 'z') {}

works nicely.
I don't think he needed to bound the array ... I am working on the assumption that he already understands that if his input data is suspect, a negative index would blow up his world. I took this as the age old "is it really safe to do the test before the use, in an if ... or are all these samples I've seen just getting lucky?" kinda question ..

Course, with Enigma's post (thanks BTW), the water gets murkier because of the overloading thing ... and I think that's going on my very short list of things I'm not sure the standard should have done (If writing an overload MUST change the semantics of an operation - as opposed to MIGHT - they should not have allowed overloading for that operator). But I guess it doesn't matter as long as we programmer's are informed and choose to avoid using the constructs we aren't wise enough to handle properly.

Time will tell.

This topic is closed to new replies.

Advertisement