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=3
和 unsigned int b=4
,那么 a-b<0
由于溢出将始终为 false。【参考方案2】:
size_t
是无符号整数类型。因此,编译器看到比较< 0
将始终为假(标准确实在发生溢出时指定了 2 的补码包装)。你应该把这个比较去掉,因为它是一个空操作(编译器可能不会为它生成任何代码)。
声明为无符号的无符号整数应遵守算术模 2n 的定律,其中 n 是数字 该特定整数大小的值表示中的位数。46
以及相应的脚注:
46) 这意味着无符号 算术不会溢出,因为 无法表示的结果 得到的无符号整数类型是 减少模数是一 大于最大值 可以用结果来表示 无符号整数类型。
【讨论】:
【参考方案3】:更新字符esIndex < 0 ||
这部分代码对机器来说完全没有意义,这就是为什么编译器会警告你——“你是不是打算做别的事情?”。
【讨论】:
【参考方案4】:我怎样才能阻止这些警告出现?我不想删除 -W 标志。
:|
只需更正您的代码,警告就会消失......就是这样......
这些警告可以帮助您生成正确、清洁、高效的代码。
【讨论】:
可重用代码从客户端自定义的头文件中绘制 const size_t 值的情况如何?在某些情况下,const 值可能会设置为零(例如,音频通道的数量),其目的是如果为零,这些循环会简单地退出编译。以一种不会产生编译器警告的方式编写它会很好。我想可以使用预处理器宏... 通过定义static const unsigned ZERO = 0;
,您可以改用x < ZERO
。没有警告,零可能会被优化掉。
@YoYoYonnY,尝试使用 clang++。没有这样的运气。但我是如此充满希望。 :) 可以禁用/启用比较行周围的警告,here。 #pragma clang diagnostic ignored "-Wtautological-compare"
以上是关于g++ 警告:无符号表达式 < 0 的比较始终为假的主要内容,如果未能解决你的问题,请参考以下文章
[C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]