使无符号整数下流抛出异常

Making unsigned integer underflow throw an exception

本文关键字:抛出异常 无符号整数      更新时间:2023-10-16

我知道在某些应用中,使用无符号整数over/underflow是获得廉价模运算的好方法。

在我的代码中,我只使用uint作为容器的索引,所以我从不想要这种行为。

  1. 这是个坏主意吗?我应该在所有地方都使用int吗?我确实需要做一些令人讨厌的事情来让for循环计数到0

  2. 是否有一种不太安全的无符号整数类型的常用实现?抛出异常的东西?

  3. 编译器(对我来说是gcc, clang)在给定的编译单元中提供了一种减少不安全行为的机制吗?

首先,一个术语上的问题:没有所谓的无符号整数下流,确切地说是,因为包围的方式(使用模运算),这可能就是您所指的短语。

第二,这是一个常见的场景吗?是的,有点。你不是唯一一个用循环做"讨厌的事情"来进行反向计数的人,我敢打赌有很多错误是人们没有做"讨厌的事情"的,结果,他们的代码中隐藏着一个令人讨厌的无限循环。请注意,我不确定我是否会说unsigned是"不安全的";像任何东西一样,它们是无限可能工作的一个子集的正确工具,并且在这个子集中它们是完全安全的。

对于是否应该使用无符号整数作为数组索引存在争议。一些标准委员会成员认为在标准库中使用它们是一个错误;我知道Stack Overflow上的一些c++社区成员也讨厌unsigned值,希望它们消失。

我个人认为,在默认情况下访问整型的整个范围是绝对重要的(为了一个"-1"哨兵值或其他什么而失去这个是不值得的),所以我认为—虽然您并不是唯一有此要求的人,但这是一个合理的要求—默认情况下使用无符号数组索引是一件好事。(负的数组索引到底是什么?语义,人!)

但这在这种情况下没有帮助。那么,你能做些什么呢?不,没有捕获无符号整数实现(至少,我知道没有,更不用说广泛了),因为这将从字面上违反c++定义的类型规则:它将引入定义良好的下溢/溢出语义,而下溢/溢出甚至不应该发生。

您必须使用有符号整数并检查"逻辑下溢"(即超出您的期望范围,例如-1)。你可以把这个行为包装在一个类中。

我想你可以实际上只是包装一个无符号整数,而你在它,添加一些额外的逻辑到operator--operator-=来检测一个包裹和抛出。

但我想我的观点是,无论你做什么,它都将在你的"代码空间"中,从而受到性能下降的影响。您无法从平台本身看出这种行为。