是否有任何C99编译器在默认设置下

很多人经常在右移运算符的讨论中指出C标准明确指出负数移位的影响是实现定义的。 我可以理解该陈述的历史基础,因为已经使用C编译器为各种不使用二进制补码算法的平台生成代码。 然而,我所知道的所有新产品开发都集中在处理器上,这些处理器除了二进制补码之外没有任何类型的整数运算的固有支持。

如果代码希望以2的幂来执行一个有符号的有符号整数除法,并且它只会用于当前或未来的体系结构,那么是否存在任何未来的编译器将解释右移运算符的现实危险还要别的吗? 如果存在切合实际的可能性,是否有任何好的方法可以提供,而不会对可读性和/或性能产生负面影响? 是否有任何其他的依赖性可以证明对操作符的行为做出彻底的假设(例如,对于不支持函数X的实现,代码将是无用的,而且如果实现不使用符号扩展右移)?

注意:我在C99和C11标签下询问,因为我期望新语言特性能够支持这样一些事情,如果支持的话,这会表明平台可能会使用算术等同于地板分割的右移,并有兴趣了解任何以任何其他方式实施右移的C99或C11编译器。


这只是众多原因之一,但考虑信号处理的情况:

1111 0001 >> 1
0000 1111 >> 1

以右移算术(SRA)的形式,你指的是你会得到以下结果:

1111 0001 >> 1 = 1111 1000
OR
-15 >> 1 = -8

0000 1111 >> 1 = 0000 0111
OR
15 >> 1 = 7

所以有什么问题? 考虑一个幅度为15“单位”的数字信号。 不管符号如何,将这个信号除以2应该产生相同的行为。 但是,对于上述的SRA,15的正信号将导致7个幅度的信号,而15的负信号将导致8个幅度的信号。 这种不均匀性会导致输出中出现直流偏置。 出于这个原因,一些DSP处理器选择实施“舍入到0”的右移算术或其他方法。 由于C99标准的措辞不变,这些处理器仍可以符合标准。

在这些处理器上, -1 >> 1 == 0

相关维基


从理论上讲,现在编译器实现中存在一些微妙之处,可能会滥用所谓的“未定义行为”,超出了后端cpu对寄存器(或“文件”或内存位置或其他)的实际整数的影响:

  • 交叉编译器是常见的东西:编译器可能会在执行简单计算时滥用依赖于实现的规格。 考虑目标体系结构实现这种方式并托管其他方式的情况。 在你的特定例子中,即使目标体系结构中的任何汇编输出会给出0(我不能想到没有这样的体系结构),编译时常量也可能最终为1。 反之亦然。 对于编译器实现者来说,不会有任何要求(除了基于用户的抱怨)以外的其他处理。

  • 考虑CLANG和其他生成中间抽象代码的编译器。 没有什么能够阻止类型机制在某些代码路径上(例如,当它可以将代码减少到常量,想到循环折叠时)在中间时间优化一些操作直到最后一点,同时让程序集后端在运行时解决此问题其他路径。 换句话说,你可能会看到混合行为。 在这种抽象中,除了C语言所期望的之外,实现者没有义务遵守任何标准。 想想所有整数数学都是由任意精度算术库完成的情况,而不是直接映射到主机CPU整数。 这个实现可以决定什么原因,这是未定义的,并且会返回0.它可以为任何已签名的算术未定义行为这样做,并且在ISO C标准中有很多,特别是包装等等。

  • 考虑(理论上)情况,编译器不是发出完整指令来执行低级操作,而是劫持子操作。 ARM的一个例子就是带有桶形移位器的ARM:一个明确的指令(即add或者其他)可以有一个范围和语义,但是子操作的操作可能会有一些不同的限制。 编译器可以利用它来限制行为可能不同的地方,例如一个案例可以设置结果标记,而另一个案例不能。 我不能想到一个具体的案例,但它有可能是一些奇怪的指令只能处理“否则正常行为”的子集,并且编译器可能会认为这是一个很好的优化,因为未定义的行为应该真的意味着未定义的行为:-)

  • 除了怪异的体系结构,在运行时你实际上会有奇怪的行为,这些都是我能想到为什么你不能假定超出未定义行为的原因的一些原因。

    尽管如此,我们还必须考虑:

  • 你要求一个C99编译器。 大多数奇怪的体系结构(即嵌入式目标)都没有C99编译器。
  • 大多数“大规模”编译器实现者处理非常大的用户代码库,并且通常通过过度优化微小的细微差异来支持面对恶梦。 所以他们没有。 或者他们以其他球员的方式进行。
  • 在有符号整数“未定义的行为”的特殊情况下,通常互补的无符号操作是一个已定义的操作,即我已经看到代码转换签名为无符号,只能执行操作并将结果重新输出。
  • 我认为我能给出的最好的直接答案是“你可能认为所有这些都不相关,但也许你不应该”。

    链接地址: http://www.djcxy.com/p/75733.html

    上一篇: Are there any C99 compilers where with default settings

    下一篇: Graphing Algorithm for many nodes