说我的size_type
是 uint64_t
,我有以下循环(其中 sz
也是 size_type
)
for ( size_type i= 0; i < sz; ++i ) {
//something
if ( i+1 == sz ) { //<-- here
///
}
}
现在使用标志 -fno-omit-frame-pointer -fsanitize=undefined -O2 -fsanitize=address
编译此文件时,我收到一个运行时错误,指出在我标记 here
的地方在上面的代码片段中,2147483647 + 1 cannot fit into integer
,确实 sz
比 2^31-1
稍大一些。然而,一切都应该没问题,因为uint64_t
可以保存该值,并且通过转换规则i+1
应提升为uint64_t
。我缺少什么?
编辑:不是这样uint64_t
总是有64
位?然后,2147...
-值只是 32
位,我们应该还好。我现在在没有 sanitizer 的情况下运行我的东西,到目前为止还没有发生崩溃。
编辑:
clang version 8.0.0-3~ubuntu18.04.1 (tags/RELEASE_800/final) Target: x86_64-pc-linux-gnu Thread model: posix
而且我还有链接器标志,如下
set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address")
也许这也有干扰?我 知道编译器资源管理器无法重现该错误,这很奇怪,需要我进一步调查。
最佳答案
在最后一次迭代期间i = UINT64_MAX - 1
,所以i+1 = UINT64_MAX
,所以i <= UINT64_MAX
在所有情况下。
for ( size_type i= 0; i < sz; ++i ) {
//something
if ( i+1 == sz ) { //<-- here
///
}
}
没有溢出。 clang 中可能存在错误,它试图进行不正确的归纳变量优化。
clang-8,rcx 递增直至达到 0。这可能会引入 off by 1 错误。
.LBB1_4:
neg rcx
.LBB1_5: # =>This Inner Loop Header: Depth=1
cmp rax, rdi
jne .LBB1_7
mov qword ptr [rsp - 8], rdi
.LBB1_7: # in Loop: Header=BB1_5 Depth=1
add rdi, 1
inc rcx
jne .LBB1_5
.LBB1_8:
而 clang-9。 rcx
递减直至达到 0。
.LBB1_7:
ret
.LBB1_6: # in Loop: Header=BB1_4 Depth=1
add rdi, 1
add rcx, -1
je .LBB1_7
.LBB1_4: # =>This Inner Loop Header: Depth=1
cmp rax, rdi
jne .LBB1_6
mov qword ptr [rsp - 8], rdi
jmp .LBB1_6
关于c++ - clang 清理程序错误地捕获整数溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59767538/