繁体   English   中英

为什么不在 C++ 中强制执行 2 的补码?

[英]Why not enforce 2's complement in C++?

新的 C++ 标准仍然拒绝指定整数类型的二进制表示。 这是因为 C++ 的实际实现不使用 2 的补码算法吗? 我觉得很难相信。 是因为委员会担心未来硬件的进步会使“位”的概念过时吗? 再次难以置信。 任何人都可以对此有所了解吗?

背景:我在一个评论线程中两次感到惊讶(Benjamin Lindley 对这个问题的回答)。 首先,来自 piotr 的评论:

有符号类型的右移是未定义的行为

其次,来自 James Kanze 的评论:

分配给 long 时,如果该值不适合 long,则结果是实现定义的

在我相信它们之前,我必须在标准中查找这些。 它们的唯一原因是适应非 2 的补整数表示。 为什么?

(编辑:C++20 现在强加 2 的补码表示,请注意有符号算术的溢出仍然未定义,并且在某些情况下,移位继续具有未定义和实现定义的行为。)

  • 定义一些不是的一个主要问题是编译器是在假设未定义的情况下构建的。 改变标准不会改变编译器,检查那些以找出假设的地方是一项艰巨的任务。

  • 即使在 2 补充机上,您的多样性也可能比您想象的要多。 两个例子:有些没有保留右移的符号,只是一个引入零的右移; DSP 中的一个共同特征是饱和算法,分配一个超出范围的值会将其剪裁到最大值,而不仅仅是丢弃高位。

我想这是因为标准说,在3.9.1[basic.fundamental]/7

本国际标准允许整数类型的 2 的补码、1 的补码和带符号的幅度表示。

我敢打赌,它来自 C 编程语言,它列出了符号和大小二进制补码补码作为6.2.6.2/2唯一允许的表示6.2.6.2/2 当 C 广泛传播时,肯定有 1 的补码系统:似乎 UNIVAC 是最常被提及的。

在我看来,即使在今天,如果您正在编写希望在任何机器上运行的广泛适用的 C++ 库,则不能假设 2 的补码。 C++ 被广泛用于做出这样的假设。

但是,大多数人不会编写这类库,因此如果您想依赖 2 的补码,则应该继续。

语言标准的许多方面都是如此,因为标准委员会非常不愿意禁止编译器以现有代码可能依赖的方式行事。 如果存在依赖于补码行为的代码,那么要求编译器的行为就像底层硬件使用二进制补码一样,将使旧代码无法使用新编译器运行。

标准委员会认为该解决方案尚不适合实施,它是允许代码以独立于机器字长或硬件特性的方式为事物指定所需的语义。 如果认为对依赖于补码行为的代码的支持很重要,请设计一种方法,使代码可以明确要求自己的补码行为,而不管底层硬件平台如何。 如果需要,为了避免使每个编译器过于复杂,请指定标准的某些方面是可选的,但符合标准的编译器必须记录它们支持哪些方面。 这种设计将允许二进制补码机器的编译器根据程序的需要支持二进制补码行为和个人补码行为。 此外,它可以将代码移植到二进制补码机器,编译器恰好包含一个补码支持。

我不确定为什么标准委员会还不允许代码以独立于底层架构和字长的方式指定行为(这样代码不会让某些机器使用签名语义进行比较,其中其他机器将使用无符号语义),但无论出于何种原因,他们还没有这样做。 对ones'-complement 表示的支持只是其中的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM