在C ++中使用签名/未签名警告静音的最少侵入性方法是什么?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (8)

我有一个套接字通信程序。协议是写入中的任何错误都是致命的,因此应该关闭连接。我的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表示错误)。我不在乎; 除完全转移之外的任何事情对连接都是致命的。另外,我不明白签名/未签名之间的(in)相等性测试是如何危险的。

我看过这里这里这里这里,但问题都是关于不比较,而答案都是“不要那样做”。

这个问题要求对警告进行静音,但是大锤“使所有签名/未签名的沉默”比较是不可取的。

怎样以尽可能少的干扰方式沉默这个警告呢?

提问于
用户回答回答于

如果您可以展示一些模板样板,另一种可能的解决方案是编写一个以不同方式处理每种类型的函数:

#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));
}
用户回答回答于

将错误条件的检测与检测到不正确的长度分开,并使用显式转换

if ( nWritten < 0 ||
     static_cast<decltype(toWrite)>(nWritten) != toWrite )
{
   // handle problems
}

小编辑:将所有负值捕获为错误,以防止未来发生变化。

所属标签

可能回答问题的人

  • 天使的炫翼

    15 粉丝531 提问35 回答
  • 旺仔小小鹿

    社区 · 运营 (已认证)

    48 粉丝0 提问27 回答
  • 富有想象力的人

    2 粉丝0 提问26 回答
  • 发条丶魔灵1

    6 粉丝525 提问25 回答

扫码关注云+社区

领取腾讯云代金券