I have a socket communication program. The protocol is that any error in writing is fatal, so the connection should be closed. My I/O code looks like this:
auto const toWrite = buf.size() * sizeof(buf[0]);
auto nWritten = ::write(fd, buf.data, toWrite);
if (toWrite != nWritten)
{
closeTheSocket();
}
This code gives warning: comparison between signed and unsigned integer expressions
on the boolean test.
I understand the evils of greater/less comparisons on signed vs unsigned, but it's unavoidable here. The signature for the ::write
system call is
#include <unistd.h> ssize_t write(int fd, const void *buf, size_t count);
In other words, my toWrite
variable is properly unsigned and the returned nWritten
is signed (-1 indicates an error). I don't care; anything other than complete transfer is fatal to the connection. Also, I don't understand how an (in)equality test between signed/unsigned could be dangerous.
I've looked here, here, here, and here, but the questions are all about less-than comparisons, and the answers are all "don't do that".
This question asks about silencing the warning, but a sledgehammer "silence all signed/unsigned" comparisons is undesirable.
How should I silence just this warning in the least intrusive manner possible?
Separate the detection of the error condition from the detection of a incorrect length and use an explicit cast
if ( nWritten < 0 ||
static_cast<decltype(toWrite)>(nWritten) != toWrite )
{
// handle problems
}
Small edit: capture all negative values as errors for a wee bit of futureproofing.