2

根据-Wstrict-overflow3 级的文档:

还警告[s] 关于简化比较的其他情况。例如:x + 1 > 1 被简化为 x > 0。

下面显示的 MWE 在级别 3 及以上(但不低于)以及如果优化设置为及以上但不低于以下时会引发以下警告-O2g++ 版本 9.3.0 和 10.2 展示了这一点。

$ g++ -O3 -Wall -Wextra -pedantic -std=c++17 -Wstrict-overflow=3 a.cpp
a.cpp: 在函数 'void std::push_heap(_RAIter, _RAIter) [with _RAIter = long unsigned int *]':a.cpp:8:1:警告:假设将 X +- C1 cmp C2 更改为 X cmp C2 -+ C1 [-Wstrict-overflow] 时不会发生有符号溢出

现场演示

MWE

#include <algorithm>

int main() {
  std::size_t v[] = {0,10,3};
  std::make_heap(std::begin(v),std::end(v));
  std::pop_heap(std::begin(v),std::end(v));
  std::push_heap(std::begin(v),std::end(v)); // <---
}

问题

  • 这是库实现中的错误吗?我没有看到任何签名类型。
  • 如何在保持-Wstrict-overflow最高 5 级的同时解决此问题?
4

1 回答 1

1
  • 这是库实现中的错误吗?我没有看到任何签名类型。

不,库实现是正确的。使用-fsanitize=undefined确认没有溢出。

该警告仅告诉您编译器假设没有发生溢出。如果它假设代码没有未定义的行为,它可以更积极地优化代码,因此它假设代码没有溢出。警告只是告诉您做出了这样的假设,因为如果您向函数提供实际导致溢出的输入,该假设可能是错误的。

所以警告的意思是“你最好不要在这里提供错误的输入,因为这会使这个优化产生不正确的结果”。

我报告了一个编译器错误(PR 96658),但严格来说,GCC 的行为与记录的一样。

  • 如何在将 -Wstrict-overflow 保持在其最高级别 5 的同时解决此问题?

的文档-Wstrict-overflow很清楚,它给出了误报,所以不要将它与 结合起来-Werror,这很愚蠢。

于 2020-08-17T13:25:17.683 回答