我有一个套接字通信程序。该协议规定,任何写入错误都是致命的,因此应关闭连接。我的I / O代码如下:
auto const toWrite = buf.size() * sizeof(buf[0]);
auto nWritten = ::write(fd, buf.data, toWrite);
if (toWrite != nWritten)
{
closeTheSocket();
}
此代码为布尔测试提供warning: comparison between signed and unsigned integer expressions
。
我了解对有符号与无符号进行更多/更少比较的弊端,但这在这里是不可避免的。 ::write
系统调用的签名是
#include <unistd.h> ssize_t write(int fd, const void *buf, size_t count);
换句话说,我的toWrite
变量正确地未签名,返回的nWritten
已签名(-1表示错误)。我不在乎;除完全传输外,其他任何事情都对连接致命。另外,我不知道在有符号/无符号之间进行(不相等)测试会多么危险。
我看过here,here,here和here,但是问题都是关于小于的比较,而答案都是“不'不这样做。
This question询问是否将警告静音,但是不希望使用大锤“使所有已签名/未签名的比较静音”。
我应该如何以尽可能不造成干扰的方式使只是这个警告静音?
答案 0 :(得分:4)
将错误条件的检测与错误长度的检测分开,并使用显式强制转换
if ( nWritten < 0 ||
static_cast<decltype(toWrite)>(nWritten) != toWrite )
{
// handle problems
}
小修改:捕获所有负值作为错误,以防将来过时。
答案 1 :(得分:1)
如果您可以裸露一些模板样板,则另一种可能的解决方案是编写一个以不同方式对待每种类型的函数:
#include <type_traits>
template <class A, class B>
constexpr bool are_different(A a, B b)
{
if constexpr (std::is_signed_v<A> and std::is_unsigned_v<B>)
{
if ( a < 0 )
return true;
else
return std::make_unsigned_t<A>(a) != b;
}
else if constexpr (std::is_unsigned_v<A> and std::is_signed_v<B>)
{
if ( b < 0 )
return true;
else
return a != std::make_unsigned_t<B>(b);
}
else
{
return a != b;
}
}
int main()
{
static_assert(are_different(1, 2));
static_assert(!are_different(1ull, 1));
static_assert(are_different(1, 2));
static_assert(are_different(1u, 2));
static_assert(are_different(1, 2u));
static_assert(are_different(-1, -1u));
static_assert(!are_different((long long)-1u, -1u));
}