In the expression of the if statement
if (SYS_FS_FileWrite(handle, buf, nbytes) == -1) {
there are used two operands of different types. The left operand of the equality operator has the type size_t
and the right operand is the integer constant -1
of the type int
.
The compiler needs to determine the common type of the operands.
In this case there are used the so-called usual arithmetic conversions.
As the rank of the type size_t
is not less than the rank of the type int
(the typs size_t
is usually an alias for the type unsigned long
and in more rare cases for type unsigned long long
) then the operand of the type int
is converted to the type size_t
.
So under the hood you have in fact
if (SYS_FS_FileWrite(handle, buf, nbytes) == ( size_t )-1) {
the same way as the returned integer constant -1
from the function is converted to the type size_t
according to the function return type
size_t SYS_FS_FileWrite(SYS_FS_HANDLE handle, const void *buf, size_t nbytes)
{
//...
return ( size_t ) -1;
//...
}
Thus the if statement may be interpreted like
if ( ( size_t )-1 == ( size_t )-1) {
provided that the function returns -1
. Otherwise the left operand of the equation has some other value returned by the function and the expression evaluates to logical false (integer value 0
)
From the C Standard (6.5.9 Equality operators)
4 If both of the operands have arithmetic type, the usual arithmetic
conversions are performed. Values of complex types are equal if and
only if both their real parts are equal and also their imaginary parts
are equal. Any two values of arithmetic types from different type
domains are equal if and only if the results of their conversions to
the (complex) result type determined by the usual arithmetic
conversions are equal.
SYS_FS_FileWrite()
returns(size_t)-1
on error, the safest thing to do would be compare the return value to(size_t)-1
rather than a plain old-1
so that you do not have to worry about the value after conversion to a common type by the usual arithmetic conversions. – Zebulon-1
to an unsigned integer type is a common and portable way to get the maximal value of that type. – Eddysizeof(size_t) < sizeof(int)
, then-1
will not be converted at all.if (UINT8_MAX==-1)
isn't going to be true on all that many implementations... – Forme-1
when return type is unsigned. Btw., it would be more readable to e.g.#define ERROR_VALUE ((size_t)-1)
and use that as return value as well as for checking the returned result. – Eddy#define ERROR_VALUE SIZE_MAX
as the error value -- that would avoid any ambiguity or portability issues. – Siegel