【问题标题】:Implementing / enforcing wraparound arithmetic in C [closed]在 C 中实现/强制执行环绕算法 [关闭]
【发布时间】:2016-11-21 23:50:49
【问题描述】:

C 标准说算术溢出是未定义的。

我想知道如何以性能友好的方式实现环绕算法。这意味着像 here 这样的溢出检查解决方案不是一种选择(因为它们会使操作减慢大约一个数量级)。

我认为解决方案将涉及编写一个汇编例程来执行此操作。是否有可用的库来执行此操作(最好用于多种架构,尽管 x86 是必须的)?

或者,是否有编译器标志(用于 gcc 和 clang)使编译器强制执行整数运算的环绕语义?

【问题讨论】:

  • “C 标准说算术溢出是未定义的。” - 大错特错!
  • 在总是定义溢出的地方使用unsigned整数或使用-fwrapv编译以获得有符号整数的可靠环绕溢出。

标签: c integer-overflow integer-arithmetic


【解决方案1】:

已签名 溢出未定义。无符号溢出包装。实现有符号环绕算法主要是在无符号数学中做所有事情。不过有几点需要注意:

  1. unsigned shortunsigned char 算术首先将操作数转换为 intunsigned int。通常是int,除非你在一个奇怪的设置中int 没有足够的范围来存储所有unsigned short 值。这意味着将shortchar 转换为unsigned shortunsigned char 用于算术仍然会产生有符号整数溢出和UB。您需要在 unsigned int 或更大的范围内进行数学运算以避免这种情况。
  2. unsigned->signed 转换在技术上由实现定义,当原始值超出结果类型的范围时。对于大多数编译器和架构来说,这应该不是问题。

或者,如果您想使用编译器标志路线,-fwrapv 会在 GCC 和 Clang 上为加法、减法和乘法生成有符号溢出包装。不过,它对INT_MIN / -1 没有任何作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 2019-07-09
    • 1970-01-01
    • 2011-04-19
    相关资源
    最近更新 更多