据我所知,有些应用程序使用无符号整数上/下溢是获得廉价模运算的好方法。
在我的代码中,我只使用uint
作为容器的索引,所以我从不想要这种行为。
这是个坏主意吗?我应该在任何地方使用int
吗?我必须做一些令人讨厌的事情才能让for循环倒数到0。
是否有常用的不安全的无符号整数类型的实现?引发异常的东西?
编译器(对我来说是gcc,clang)是否为给定编译单元中的不安全行为提供了一种机制?
答案 0 :(得分:5)
首先,一个术语狡辩:没有无符号整数下溢这样的东西,正是因为它们环绕的方式(使用模运算),这可能是你的意思。
其次,这是一个常见的场景吗?是的,有点儿。你并不是唯一一个做出令人厌恶的事情的人。用循环进行反向计数,我打赌那里有大量的错误,其中人们避免完成"令人厌恶的事情"结果,他们的代码中隐藏着一个令人讨厌的无限循环。请注意,我不确定我是否会打电话给未签约的人,不安全的"结果是;像任何东西一样,它们是无限可能工作子集的正确工具,并且在该子集中它们非常安全。
关于是否应该将无符号整数用于数组索引存在争议。一些标准委员会成员认为他们在标准库中的使用是错误的;我知道Stack Overflow上的c++社区的几位成员也讨厌unsigned
值,并希望他们离开。
就我个人而言,我认为默认情况下访问整个范围的整数是绝对至关重要的(对于单个" -1"哨兵值或其他任何东西而言,丢失它是不值得的,所以我认为 - 虽然你并不孤单,但这是一个明智的要求 - 默认情况下使用无符号数组索引是件好事。 (还有什么是负数组索引?语义,人!)
但是在这种情况下,这对你没有帮助。所以你能对它做点啥?不,没有陷阱无符号整数实现(至少,不是我所知道的,更不用说普遍存在),因为这实际上违反了C ++定义的类型规则:它会很好地引入 - 定义的下溢/溢出语义为一种甚至不可能出现下溢/溢出的类型。
您必须使用有符号整数并检查"逻辑下溢" (即自己离开你的所需范围,比方说-1)。您可以将此行为包装在一个类中。
我认为你可以实际上只是包裹一个无符号整数,然后在operator--
和operator-=
添加一些额外的逻辑以检测包裹在附近扔。
但我想我的观点是,无论你做什么,它都会出现在你的代码空间中。因而性能下降。您可以从平台本身剔除此行为。