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

| 新的C ++标准仍然拒绝指定整数类型的二进制表示形式。这是因为存在一些不使用2的补码算术的C ++实际实现吗?我觉得很难相信。是因为委员会担心硬件的未来发展会导致“位”的概念过时吗?再次令人难以置信。谁能对此有所启示? 背景:我在一个评论线程中两次感到惊讶(本杰明·林德利(Benjamin Lindley)对这个问题的回答)。首先,从piotr的评论:   有符号类型的右移是未定义的行为 其次,从詹姆斯·坎泽的评论:   分配长型时,如果该值不适合长型,则结果为   实现定义 在我相信它们之前,我必须在标准中查找它们。它们的唯一原因是要容纳非2的补码整数表示形式。为什么?     
已邀请:
定义未定义的主要问题是,编译器是在未定义的前提下构建的。更改标准不会更改编译器,而要检查编译器以找出进行假设的位置是一项艰巨的任务。 即使在2补码机上,您也可能比您想像的更多。有两个例子:有些没有保持右移的符号,只是右移引入了零。 DSP的一个常见功能是饱和算法,在其中分配一个超出范围的值会将其限幅到最大,而不仅仅是丢弃高阶位。     
在我看来,即使在今天,如果您正在编写要在任何计算机上运行的广泛适用的C ++库,那么也不能假设2的补码。 C ++太广泛地用于进行这样的假设。 不过,大多数人不会编写此类库,因此,如果您想依赖2 \的补码,则应该继续进行下去。     
我想这是因为标准在“ 0”中说   本国际标准允许整数类型使用2的补码,1的补码和带符号的幅度表示。 我愿意打赌,它来自C编程语言,该语言列出了符号和大小,二的补码和一的补码作为
6.2.6.2/2
中唯一允许的表示形式。当C广泛传播时,肯定会有1的补码系统:似乎最常提到UNIVAC。     
语言标准的许多方面都是如此,因为标准委员会一直极力禁止编译器以现有代码可能依赖的方式行事。如果存在依赖于补码行为的代码,则要求编译器的行为就像基础硬件使用二进制补码一样,将使较旧的代码无法使用较新的编译器运行。 标准委员会尚未实现的解决方案是,允许代码以与机器字长或硬件特征无关的方式为事物指定所需的语义。如果认为对依赖于补码行为的代码的支持很重要,请设计一种手段,使代码可以明确地要求补码行为,而与底层硬件平台无关。如果需要,为避免每个单独的编译器过于复杂,请指定该标准的某些方面是可选的,但是符合标准的编译器必须记录它们支持哪些方面。这样的设计将允许补码机的编译器根据程序的需要支持补码行为和补码行为。此外,它还可以将代码移植到恰好包含对补码支持的编译器的二进制补码机器上。 我不确定为什么标准委员会尚未允许代码以任何方式独立于基​​础体系结构和字长来指定行为(因此,代码中不会有某些机器使用签名语义来实现)比较其他机器将使用无符号语义的地方),但是由于任何原因,它们仍然没有这样做。对“补码”表示的支持只是其中一部分。     

要回复问题请先登录注册