g++ 警告:无符号表达式 < 0 的比较始终为假

Posted

技术标签:

【中文标题】g++ 警告:无符号表达式 < 0 的比较始终为假【英文标题】:g++ warning: comparison of unsigned expression < 0 is always false 【发布时间】: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:我一直不明白为什么默认情况下会禁用警告。 【参考方案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"

以上是关于g++ 警告:无符号表达式 < 0 的比较始终为假的主要内容,如果未能解决你的问题,请参考以下文章

作业问题 C++ 中的警告

为啥无符号类型没有下溢警告?

[C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]

[C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]

有符号/无符号比较

为啥 C 没有无符号浮点数?