Ben*_*Ben 3 c++ integer-overflow undefined-behavior unsigned-integer
以下证据表明:
inline
constexpr std::size_t prev(std::size_t i) {
--i;
return i;
}
int main() {
static const std::size_t i = 0;
static_assert(prev(i) == std::size_t(-1), "Decrementing should give std::size_t(-1)");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
那个快乐地汇编着-std=c++14.
我遇到了这个,因为我有一个循环索引,std::vector并想要向后循环,所以我把它改为
for (std::size_t i = std::min(idx, v.size() - 1); i != std::size_t(-1); --i) { ... }
Run Code Online (Sandbox Code Playgroud)
现在,我意识到我可以使用std::vector::reverse_iterator,但我现在的真正问题是,我期待定义的行为是什么?
size_t 是未指定的无符号整数.
C++中的所有无符号整数都被建模为模2 n的整数环的元素,用于特定于该无符号整数类型的某个数字n.
当您将有符号整数转换为无符号整数时,您将获得整数环中的值,模2 n为该无符号类型的常量n.对于-1,这是2 n -1.
当您将0作为无符号整数类型递减时,得到2 n -1.
这两个值是相同的.
参见C++标准中的[basic.fundamental] 3.9.1/4:
无符号整数应遵守算术模2 n的定律, 其中n是该特定整数大小的值表示中的位数.
(引用取自N3690,最近的标准草案,但它代表的事实不会很快改变;段落编号可能.)
查找有关如何从有符号整数进行转换的引用将涉及更多标准追逐; 但它最终成为你想要的.
是的,这种行为是有保证的.
std::size_t是无符号整数类型.无符号整数的算术总是有明确定义的语义:
无符号整数运算总是以2 n为模执行 ,其中n是该特定整数中的位数.
特别考虑内置的预减量和后减量运算符:
[T]他的表达
--x完全等同于x -= 1....
[T]表达式x--修改其操作数的值,就好像通过评估一样x -= 1
因此减量运算符确实执行算术运算.
| 归档时间: |
|
| 查看次数: |
451 次 |
| 最近记录: |