Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing size_t to -1 [duplicate]

Note: it has been suggested that this question duplicates Can I compare int with size_t directly in C?, but the question here specifically asks about comparing size_t with a negative value. For this reason, it should be re-opened. (And besides, it has generated a lot of thoughtful discussion!)

I'm staring at some library code (I am looking at you, Microchip), declared to return a size_t:

size_t SYS_FS_FileWrite(SYS_FS_HANDLE handle, const void *buf, size_t nbytes);

That is documented as returning -1 on an error. But size_t is an unsigned value. So, in theory and/or in practice, is the following allowed?

if (SYS_FS_FileWrite(handle, buf, nbytes) == -1) {
    report_errror();
}
like image 554
fearless_fool Avatar asked Mar 06 '26 10:03

fearless_fool


2 Answers

It is impossible for a routine that returns a size_t to return −1, but it is perfectly fine for it to return the result of converting −1 to size_t (presuming the relevant environment does not need that value for any conflicting purpose). If the documentation states the latter, it is fine. If it states the former, the documentation is sloppily written and probably means the latter.

In a comparison of some size_t value x to -1, as in x == -1, the value −1 will be converted to the type size_t if the rank of size_t equals or exceeds the rank of int. This is the case in most C implementations and would be expected in an implementation that uses −1 converted to size_t as a return value. In a C implementation in which size_t had lower rank than int, x could be converted to int (depending on some specifics of the types). That would not change the value, and x == -1 would always evaluate as false.

Per a request in the comments for a test of whether SYS_FS_FileWrite(handle, buf, nbytes) == -1 is a safe test for SYS_FS_FileWrite returning −1 converted to size_t in light of the fact that the usual arithmetic conversions might not produce the desired results, a suitable test is _Static_assert((size_t) -1 == -1, "size_t type is too narrow.");. Also, the test could be written as SYS_FS_FileWrite(handle, buf, nbytes) == (size_t) -1.

like image 154
Eric Postpischil Avatar answered Mar 09 '26 01:03

Eric Postpischil


Yes, it is allowed and it will work as intended.

When comparing the integer constant -1 (which has type int) with a value of type size_t, the integer constant -1 will be implicitly converted to size_t. Assuming that size_t has a width of 64 bits, it will be converted to the value 0xFFFFFFFFFFFFFFFF. The return value of the function SYS_FS_FileWrite will also have the value 0xFFFFFFFFFFFFFFFF. Therefore, the comparison will work as desired.

As pointed out in one of the other answers, the ISO C standard does allow a compiler implementation to define the data type size_t in such a way that its rank is smaller than int. In the hypothetical case of this actually happening, the statements in my previous paragraph would not apply. The integer constant -1 would retain its value and would not be converted to a positive value, so that the comparision would always evaluate to false. However, this is only a theoretical concern. In practice, you can rely on size_t having a rank that is equal to or higher than int.

It does not make much sense that the documentation states that the function will return -1. It would make more sense for the documentation to state that it will return -1 converted to a size_t, i.e. that it will return the value (size_t)-1.

like image 40
Andreas Wenzel Avatar answered Mar 09 '26 01:03

Andreas Wenzel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!