2016-11-21 81 views
-3

C标准规定算术中的溢出未定义。在C中实现/实施环绕算术运算C

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

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

或者,是否有一个编译器标志(gcc & clang)使编译器强制执行整数算术的环绕语义?

+3

“C标准说算术中的溢出是未定义的。” - 这是非常错误的! – Olaf

+1

使用总是定义了溢出的'unsigned'整数或使用'-fwrapv'进行编译,以在有符号整数上获得可靠的环绕溢出。 – PSkocik

回答

3

签名溢出未定义。未签名的溢出包装。实现有符号包络算术主要是在无符号数学中做所有事情。有几件事情要小心,虽然:

  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没有任何作用。