In C89 (and historical K&R implementations), the meaning of the remainder operator for negative operands was implementation defined. This was changed in the C99 standard [ISO/IEC 9899-1999].
Because not all C compilers are strictly C99 conforming, you cannot rely on the behavior of the % operator if you need to run on a wide range of platforms with many different compilers.
...
The result of the
/operator is the quotient from the division of the first operand by the second; the result of the%operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.
and
When integers are divided, the result of the
/operator is the algebraic quotient with any fractional part discarded. If the quotienta/bis representable, the expression(a/b)*b + a%bshall equala.
...
This code also violates recommendation ERR02-C. Avoid in-band error indicators.
Noncompliant Code Example
...
However, this noncompliant code example violates recommendation INT01-C. Use rsize_t or size_t for all integer values representing the size of an object. There is also a possibility that (index + 1) could result in a signed integer overflow in violation of rule INT32-C. Ensure that operations on non-atomic signed integers do not result in overflow.
Compliant Solution (Unsigned Types)
...
CERT C++ Secure Coding Standard: INT10-CPP. Do not assume a positive remainder when using the % operator
ISO/IEC 9899-1999 Section 6.5.5, "Multiplicative operators"
...
MITRE CWE: CWE-129, "Unchecked Array Indexing"
Bibliography
[Beebe 2005]
[Microsoft 2007] C Multiplicative Operators
[Sun 2005] Appendix E, "Implementation-Defined ISO/IEC C90 Behavior"
...