.ds RH Relational Operator Coverage
.bp
.sp
.NH 1
Relational Operator Coverage
.XS
   Relational Operator Coverage
.XE
.LP
There are two goals for relational operator coverage:
.IP (1)
Probe off-by-one errors.  For example, for 
.sp
    if (length >= 100)
.sp
branch coverage requires some \fHlength\fR smaller than 100.  However, we
don't want to try just any such \fHlength\fR -- we'd like one only
slightly smaller, one that makes the expression "barely false".  Such
a value is more likely to discover that 100 is the wrong value.  We
also want the expression to be "barely true", to have the smallest
value of \fHlength\fR that makes the expression true.  That is, we
want \fHlength\fR to be exactly 100.
.IP (2)
Force
test cases that make the operator actually used yield a different
value from another operator that might have been used.
Suppose we have the following code:
.nf

    if (a + b < c + d )

.fi
A common mistake in such code is using "<" when "<=" is correct.
Many tests that satisfy branch coverage would cause the
correct and incorrect programs to take the same branch in the same
direction - giving very little evidence that the common mistake wasn't
make.  A better test would cause the two programs to take the branch
in different directions.  That will only happen if the coverage
condition \fHA+B==C+D\fR is satisfied.
.LP
Note that these two goals often overlap.
.LP
For each of the relational operators, the following tables describe
boundary conditions and likely mis-uses, together with the test
conditions to rule them out.  In all cases, \fBepsilon\fR is 1 (in the
current implementation).
.TS
allbox tab(#) ;
c s s
c c c
l l l. 
L < R
Condition # Rule out with # Special case for Integers
>#L!=R
<=, barely false#L==R
barely true#L < R <= L + epsilon # L == R - 1 
.TE
.LP
.TS
allbox tab(#) ;
c s s
c c c
l l l. 
L <= R
Condition # Rule out with # Special case for Integers
<, barely true#L==R
>=#L!=R
barely false#L > R >= L - epsilon # L == R + 1 
.TE
.LP
.TS
allbox tab(#) ;
c s s
c c c
l l l. 
L > R
Condition # Rule out with # Special case for Integers
<#L!=R
>=, barely false#L==R
barely true#L > R >= L - epsilon # L == R + 1
.TE
.LP
.TS
allbox tab(#) ;
c s s
c c c
l l l. 
L >= R
Condition # Rule out with # Special case for Integers
>, barely true#L==R
<=#L!=R
barely false#L < R <= L + epsilon # L = R - 1
.TE
.LP
There are no coverage conditions for == and !=.  The most likely fault is
using one when the other is correct; such a fault is automatically
ruled out whenever the operator is executed (as is ensured by
multi-condition coverage).
.LP
The \fBgreport\fR output for relational operator coverage looks like this:
.nf

   "example1.c", line 9: operator < might be <=. (L == R)
   "example1.c", line 9: operator < is never barely true. (L == R-1)

.fi
The parenthetical comment suggests the test condition that must be
satisfied.  \fBL\fR stands for the left-hand side of the relational
expression; \fBR\fR for the right-hand side.
.LP
Once the coverage condition is satisfied, nothing regarding it will appear
in the report unless the \fB-all\fR option is given:
.nf

"lc.c", line 275: operator <= might be >=.  (L != R) [1]
"lc.c", line 275: operator <= might be <.  (L == R) [3]

.fi
The number in brackets is the condition count, the number of times the
test condition has been satisfied.
.NH 2
Warnings
.LP
GCT issues a warning that many versions of \fIlint(1)\fR do not:
.nf

a == b;

yields

"Warning:  == can have no effect."

.fi
