在 C++ 中消除 signed/unsigned 警告的干扰最小的方法是什么?
What is the least intrusive way to silence a signed/unsigned warning in C++?
我有一个套接字通信程序。该协议是任何写入错误都是致命的,因此应该关闭连接。我的 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
。
我理解 greater/less 对有符号和无符号进行比较的弊端,但这在这里是不可避免的。 ::write
系统调用的签名是
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
换句话说,我的 toWrite
变量是正确无符号的,而返回的 nWritten
是有符号的(-1 表示错误)。我不在乎;除了完全传输之外的任何事情对连接都是致命的。另外,我不明白 signed/unsigned 之间的(不)等式测试有何危险。
我看了here, here, here, and ,但是题都是小于比较,答案都是"don't do that"。
This question 询问有关使警告静音的问题,但是大锤 "silence all signed/unsigned" 比较是不可取的。
我应该如何以尽可能不干扰的方式使仅此警告静音?
将错误条件的检测与不正确长度的检测分开,并使用显式转换
if ( nWritten < 0 ||
static_cast<decltype(toWrite)>(nWritten) != toWrite )
{
// handle problems
}
小编辑:将所有负值捕获为错误,以防万一。
如果您可以公开一些模板样板,另一种可能的解决方案是编写一个以不同方式处理每种类型的函数:
#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));
}
我有一个套接字通信程序。该协议是任何写入错误都是致命的,因此应该关闭连接。我的 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
。
我理解 greater/less 对有符号和无符号进行比较的弊端,但这在这里是不可避免的。 ::write
系统调用的签名是
#include <unistd.h> ssize_t write(int fd, const void *buf, size_t count);
换句话说,我的 toWrite
变量是正确无符号的,而返回的 nWritten
是有符号的(-1 表示错误)。我不在乎;除了完全传输之外的任何事情对连接都是致命的。另外,我不明白 signed/unsigned 之间的(不)等式测试有何危险。
我看了here, here, here, and
This question 询问有关使警告静音的问题,但是大锤 "silence all signed/unsigned" 比较是不可取的。
我应该如何以尽可能不干扰的方式使仅此警告静音?
将错误条件的检测与不正确长度的检测分开,并使用显式转换
if ( nWritten < 0 ||
static_cast<decltype(toWrite)>(nWritten) != toWrite )
{
// handle problems
}
小编辑:将所有负值捕获为错误,以防万一。
如果您可以公开一些模板样板,另一种可能的解决方案是编写一个以不同方式处理每种类型的函数:
#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));
}