为什么会出现此警告?如果我检查边界,这不是一个真正的假设.以及如何解决?
如果num_actions_to_skip设置为1而不是2,则错误消失.
谢谢
error: assuming signed overflow does not occur when assuming that (X - c) <= X is always true [-Werror=strict-overflow]
cc1plus: all warnings being treated as errors
Run Code Online (Sandbox Code Playgroud)
上 if (loc >= 0 && loc < action_list.count()) {
const QList<QAction *> &action_list = tool_menu->actions();
static const int num_actions_to_skip = 2;
const int loc = action_list.count() - num_actions_to_skip;
if (loc >= 0 && loc < action_list.count()) {
tool_menu->insertAction(action_list.at(loc),
action);
}
Run Code Online (Sandbox Code Playgroud)
它始于
Q_ASSERT_X(i >= 0 && i < p.size()
Run Code Online (Sandbox Code Playgroud)
在qlist.h:454,执行相同的检查,并抛出此错误,只是
tool_menu->insertAction(action_list.at(action_list.count() - 2),
action);
Run Code Online (Sandbox Code Playgroud)
你只需要重新思考你的逻辑.
static const int num_actions_to_skip = 2;
const int loc = action_list.count() - num_actions_to_skip;
if (loc >= 0 && loc < action_list.count()) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
显然action_list.count()是一个常量值(至少它不会随着执行此代码而改变),编译器能够解决这个问题.
让我们简化一下,替换num_actions_to_skip为2,减少action_list.count()到count.然后我们可以重新表达loc为count - 2.
你的if病情变成:
if (count - 2 >= 0 && count - 2 < count)
Run Code Online (Sandbox Code Playgroud)
这是等效的(假设,正如编译器警告所说,没有发生溢出):
if (count >= 2 && -2 < 0)
Run Code Online (Sandbox Code Playgroud)
下半部分,-2 > 0显然是正确的,所以你可以安全地放弃它,这让我们失望了
if (count >= 2)
Run Code Online (Sandbox Code Playgroud)
重新替换原始条款,这给了我们:
static const int num_actions_to_skip = 2;
// const int loc = action_list.count() - num_actions_to_skip;
if (action_list.count() >= num_actions_to_skip) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
编译器警告您,如果存在整数溢出,它正在执行可能无效的优化(允许假设没有溢出,因为如果行为未定义).它很友好地警告你 - 这对你来说很幸运,因为它指出你的代码正在做一些它不需要的事情.
我不知道你是否需要保留声明loc; 这取决于你以后是否使用它.但是如果你按照我建议的方式简化代码,它应该以相同的方式工作,并且更容易阅读和理解.
如果您收到编译器发出的警告消息,那么您的目标不应仅仅是让消息消失; 它应该是向下钻取并找出编译器警告你的内容,以及你的代码导致该问题的原因.
您比我更了解此代码的上下文.如果您查看修订版本,您可能会发现它更清楚地表达了意图.
从这个GCC资源:
-Wstrict溢出
-Wstrict溢出=正
此选项仅在-fstrict-overflow处于活动状态时处于活动状态.它会警告编译器根据没有发生签名溢出的假设进行优化的情况.请注意,它不会警告代码可能溢出的所有情况:它只会警告编译器实现某些优化的情况.因此,此警告取决于优化级别.
如果所涉及的变量的值实际上发生溢出,那么假定未发生签名溢出的优化是完全安全的.因此,此警告很容易产生误报:对代码实际上不是问题的警告.为了帮助关注重要问题,定义了几个警告级别.在估计循环所需的迭代次数时,不会发出使用未定义的有符号溢出的警告,特别是在确定是否将执行循环时.
-Wstrict溢出= 1
警告有疑问且容易避免的案件.例如,使用-fstrict-overflow,编译器将x + 1> x简化为1. -Wall启用此级别的-Wstrict-overflow; 更高级别不是,必须明确要求.
-Wstrict溢出= 2
还警告其他比较被简化为常数的情况.例如:abs(x)> = 0.这只能在-fstrict-overflow有效时简化,因为abs(INT_MIN)溢出到INT_MIN,小于零.-Wstrict-overflow(没有级别)与-Wstrict-overflow = 2相同.
-Wstrict溢出= 3
还警告其他简化比较的情况.例如:x + 1> 1被简化为x> 0.
-Wstrict溢出= 4
还警告上述案例未涵盖的其他简化.例如:(x*10)/ 5简化为x*2.
-Wstrict溢出= 5
还要警告编译器减少比较中涉及的常量的大小的情况.例如:x + 2> y被简化为x + 1> = y.这仅在最高警告级别报告,因为此简化适用于许多比较,因此此警告级别会产生大量误报.
| 归档时间: |
|
| 查看次数: |
4567 次 |
| 最近记录: |