A character array may not be subtracted from a pointer but one pointer can be subtracted from another pointer if the both pointers point to elements of the same array or one past the last element of the array.
From the C Standard (6.5.6 Additive operators)
9 When two pointers are subtracted, both shall point to elements of
the same array object, or one past the last element of the array
object; the result is the difference of the subscripts of the two
array elements. The size of the result is implementation-defined, and
its type (a signed integer type) is ptrdiff_t defined in the
header. If the result is not representable in an object of
that type, the behavior is undefined. In other words, if the
expressions P and Q point to, respectively, the i-th and j-th elements
of an array object, the expression (P)-(Q) has the value i−j provided
the value fits in an object of type ptrdiff_t. Moreover, if the
expression P points either to an element of an array object or one
past the last element of an array object, and the expression Q points
to the last element of the same array object, the expression
((Q)+1)-(P) has the same value as ((Q)-(P))+1 and as -((P)-((Q)+1)),
and has the value zero if the expression P points one past the last
element of the array object, even though the expression (Q)+1 does not
point to an element of the array object.106
So a question arises: what is s
in the expression found-s
?
The C Standard answers (6.3.2.1 Lvalues, arrays, and function designators)
3 Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array
object has register storage class, the behavior is undefined.
So in the above pointed expression s
is converted to pointer to its first element and in fact the expression can be equivalently rewritten for clarity like
found - &s[0]
But of course knowing this implicit conversion of array designators to pointers it is simpler to write
found - s
The result of the expression is the number of elements of the array between two pointers.
Sometimes beginners make the following error knowing nothing about such a conversion. They write for example
char s[] = "Hello";
if ( s == "Hello" )
{
// ...do something
}
However in the condition of the if statement the stored strings are not compared. There are compared addresses of the first element of the array s and of the first element of the string literal. As the array and the literal occupy different extents of memory the result of the condition evaluates to false.