Cast ssize_t or size_t

2020-06-12 02:29发布

问题:

In source files which I am using in my project, there is a comparison between ssize_t and size_t variables:

ssize_t sst;
size_t st;

if(sst == st){...}

I would like to get rid of the warning:

warning: comparison between signed and unsigned integer expressions

But I am not sure, which variable should I cast to the other?

if((size_t)sst == st){...}

or

if(sst == (ssize_t)st){...}

What is safer, better, cleaner? Thanks

回答1:

There is no one right answer to this question. There are several possible answers, depending on what you know a priori about the values that those variables may take on.

  • If you know that sst is non-negative, then you can safely cast sst to size_t, as this will not change the value (incidentally, this is what happens if you have no cast at all).

  • If sst might be negative but you know that st will never be larger than SSIZE_MAX, then you can safely cast st to ssize_t, as this will not change the value.

  • If sst might be negative, and st might be larger than SSIZE_MAX, then neither cast is correct; either one could change the value, resulting in an incorrect comparison. Instead, you would do the following if (sst >= 0 && (size_t)sst == st).

If you’re not absolutely certain that one of the first two situations applies, choose the third option as it is correct in all cases.



回答2:

Either will work fine as long as both values fit in the positive representable range of ssize_t.

If either value doesn't, you could end up in trouble - check those cases before testing for equality:

if ((sst >= 0) && (st <= SSIZE_MAX) && (sst == (ssize_t)st))
{
  ...
}

(I'm sure the C++ people will recommend you avoid the C-style cast entirely - I have no doubt someone will comment or answer and let you know the right way to do that in C++.)