【问题标题】:Coverity complains about htonl operands but why?Coverity 抱怨 htonl 操作数,但为什么呢?
【发布时间】:2021-02-05 03:02:10
【问题描述】:

此代码将本地切换转换为传出网络顺序布尔值(实际上是 32 位 uint),并且至少有 10 年的历史,但 Coverity 最近才开始抱怨它。我不明白问题是什么以及它在哪里得到“操作数|”从。问题是 htonl 只适用于 32 位值,而我们有 16 位的 hton 吗? 这是误检吗?

struct network_response_t {
    uint32_t exclusive;
}

bitmap16_t mode_t {
  TYPE_MIXED = 0x0,
  TYPE_EXCLUSIVE = 0x1,
  ...
}

mode_t local_mode;
network_response_t response;

response.exclusive = htonl((local_mode & TYPE_EXCLUSIVE) ? 1 : 0);

错误:

操作数不影响结果 (CONSTANT_EXPRESSION_RESULT) result_independent_of_operands: (__uint16_t)((__uint32_t)((local_mode & TYPE_EXCLUSIVE) ? 1 : 0) & 65535) >> 8 为 0 与值无关 的操作数。这作为“|”的按位第二个操作数出现。

【问题讨论】:

  • uint32_t mode_exclusive = (local_mode & TYPE_EXCLUSIVE) ? 1 : 0; response.exclusive = htonl(mode_exclusive); 是一种解决方法吗? mode_t 似乎是 uint16_t(因为它是用 bitmap16_t 定义的),这可能是问题所在。错误消息中对__uint16_t 的额外转换可能证实了这一点,否则,我认为没有理由。

标签: c++ c networking coverity htonl


【解决方案1】:

这是误报。在 little-endian 平台上,htonl 执行 endian 交换,提取参数的字节并使用按位 OR 运算符以相反的顺序将它们重新组合在一起。 Coverity 正确地意识到其中一个字节将始终为零,因为在这种情况下原始参数始终为 0 或 1。但得出事实是无意的结论是错误的。

我建议将此问题报告给 Coverity 的支持团队,以便他们修复。

【讨论】:

  • 感谢您的解释,现在这很有意义,而且对 Coverity 来说这是一个奇怪的假设。
  • 检查的基本思想是合理的:如果一个完整的表达式总是评估为一个常量,尽管有可变的输入,那么可能有问题(这种情况经常由于运算符优先级错误而发生)。但在这里,它只是一个恒定的子表达式,仅此一个 (IMO) 并不足以证明其发现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 2020-08-12
  • 2016-02-27
  • 1970-01-01
  • 2017-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多