如何解决为什么即使没有涉及签名的类型,std :: push_heap也会生成-Wstrict-overflow = 3警告?
根据-Wstrict-overflow
,第3级文档:
还警告其他简化比较的情况。例如:x + 1> 1简化为x> 0。
如果优化设置为-O2
,但不低于3,则下面显示的MWE会在级别3和更高级别(但不低于 AND )上发出以下警告。 g ++版本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)[带有_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的同时解决此问题?
解决方法
- 这是库实现中的错误吗?我什么都看不到任何签名类型。
不。该库的实现是正确的。使用-fsanitize=undefined
确认没有溢出。
警告仅告诉您编译器假定没有溢出发生。如果假定代码没有未定义的行为,则可以更积极地优化代码,因此可以假定代码没有溢出。警告只是告诉您进行了这样的假设,因为如果您向函数提供的输入实际上确实导致溢出,则该假设可能是错误的。
因此,警告表示“您最好不要在此处提供错误的输入,因为那样会使该优化产生不正确的结果”。
我已经报告了一个编译器错误(PR 96658),但严格来说,GCC的行为如所记录。
- 如何在保持-Wstrict-overflow最高水平5的同时解决此问题?
-Wstrict-overflow
的文档很明显会带来误报,因此不要将其与-Werror
结合使用,这很愚蠢。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。