【问题标题】:g++ warning: comparison of unsigned expression < 0 is always falseg++ 警告:无符号表达式 < 0 的比较始终为假
【发布时间】:2010-08-30 07:17:05
【问题描述】:

为了编译我的 C++ 代码,我使用了 -W 标志,这会导致警告:

警告:无符号表达式

我认为这被认为是一个错误并已在 GCC 4.3 版本中修复,但我使用的是 GCC 4.1

这里明显有问题的代码:

void FieldGroup::generateCreateMessage (const ApiEvent::GroupData &data, omsgstream &result) const {
  dblog << debug;

  // Write out the data fields we care about, in the order they were specified
  for (size_t index = 0; index < fields.size(); ++index) {
    size_t esIndex = clsToES[index];
    if (esIndex < 0 || esIndex >= data.fields.length()) {
      ostringstream buf;
      buf << "Invalid field " << index << " (index in ES data set " << esIndex << ", " << data.fields.length() << " fields returned)";
      throw InvalidDataException (buf.str());
    }
    fields[index].writeData (data.fields[esIndex], result);
  }
}

我收到的警告:

dbtempl.cpp:在成员函数“void ECONZ::FieldGroup::generateCreateMessage(const nz::co::econz::eventServer::ApiEvent::GroupData&, ECONZ::omsgstream&) const”中: dbtempl.cpp:480:警告:无符号表达式的比较

我怎样才能阻止这些警告出现?我不想删除 -W 标志。

【问题讨论】:

  • 只是一个小评论:编译器可能有错误,但这些真的很少见。因此,当编译产生警告时,请首先检查您的代码,不要认为这是编译器的错误。
  • 我的错。我有点误读了这里发现的 gnu 错误报告:gcc.gnu.org/bugzilla/show_bug.cgi?id=23587
  • 有趣:如果您在 GCC 或 G++ 编译器中将无符号数量与“
  • 确实如此。错误是警告并不总是被提出;)
  • @Jonathan Leffler:我一直不明白为什么默认情况下会禁用警告。

标签: c++ gcc gcc-warning


【解决方案1】:

您正在测试一个正值是否低于 0。

size_t 是无符号的,所以至少为 0。

这可能永远不会发生,编译器只需删除测试即可优化。警告在这里告诉您,因为如果有人这样做,那可能是一个错误。

在你的情况下,你可能只是删除测试,它应该没问题。

【讨论】:

  • 只是一个评论,因为它发生在我身上:如果你减去 unsigned int,例如unsigned int a=3unsigned int b=4,那么 a-b&lt;0 由于溢出将始终为 false。
【解决方案2】:

size_t 是无符号整数类型。因此,编译器看到比较&lt; 0 将始终为假(标准确实在发生溢出时指定了 2 的补码包装)。你应该把这个比较去掉,因为它是一个空操作(编译器可能不会为它生成任何代码)。

声明为无符号的无符号整数应遵守算术模 2n 的定律,其中 n 是数字 该特定整数大小的值表示中的位数。46

以及相应的脚注:

46) 这意味着无符号 算术不会溢出,因为 无法表示的结果 得到的无符号整数类型是 减少模数是一 大于最大值 可以用结果来表示 无符号整数类型。

【讨论】:

    【解决方案3】:

    更新字符esIndex &lt; 0 ||

    这部分代码对机器来说完全没有意义,这就是为什么编译器会警告你——“你是不是打算做别的事情?”。

    【讨论】:

      【解决方案4】:

      我怎样才能阻止这些警告出现?我不想删除 -W 标志。

      :|

      只需更正您的代码,警告就会消失......就是这样......

      这些警告可以帮助您生成正确、清洁、高效的代码。

      【讨论】:

      • 可重用代码从客户端自定义的头文件中绘制 const size_t 值的情况如何?在某些情况下,const 值可能会设置为零(例如,音频通道的数量),其目的是如果为零,这些循环会简单地退出编译。以一种不会产生编译器警告的方式编写它会很好。我想可以使用预处理器宏...
      • 通过定义static const unsigned ZERO = 0;,您可以改用x &lt; ZERO。没有警告,零可能会被优化掉。
      • @YoYoYonnY,尝试使用 clang++。没有这样的运气。但我是如此充满希望。 :) 可以禁用/启用比较行周围的警告,here#pragma clang diagnostic ignored "-Wtautological-compare"
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-06
      • 2013-11-11
      • 2011-04-09
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      相关资源
      最近更新 更多