在C语言中,当左侧操作数为负值时,按位左移位操作调用未定义的行为.

ISO C99相关报价(6.5.7/4)

E1<<E2的结果是E1左移E2位位置;空出的位是带零的fiLled.如果E1具有无符号类型,则结果值为E1×2E2,减go 模数 比结果类型中可表示的最大值大1.如果E1有签名的 类型和非负值,并且E1×2E2在结果类型中可表示,则即 结果值;否则为the behavior is undefined.

但是在C++中,行为是很好定义的.

ISO C++-03(5.8/2)

E1<<E2的值是E1(解释为位模式)左移E2位位置;空出的位是零填充的.如果E1为无符号类型,则结果值为E1乘以2的E2次幂,如果E1为无符号长整型,则模ULONG_MAX+1减go ,否则为UINT_MAX+1. [注:常量ULONG_MAX和UINT_MAX在标题中定义).]

这意味着

int a = -1, b=2, c;
c= a << b ;

调用C中的未定义行为,但行为在C++中定义良好.

是什么迫使ISO C++委员会考虑定义良好的行为,而不是C语言中的行为?

另一方面,当左操作数为负时,按位右移操作的行为是implementation defined,对吗?

我的问题是,为什么左移操作调用C中未定义的行为,为什么右移运算符只调用实现定义的行为?

附注:请不要这样回答"这是未定义的行为,因为标准是这样说的".:p

推荐答案

您复制的段落讨论的是无符号类型.行为is未在C++中定义.从上一个C++0x草案开始:

E1<;<;E2的值为E1 E2位位置左移;空出 位是零填充的.如果E1有一个 无符号类型,结果的值 是E1×2E2,模再减一 大于可表示的最大值 在结果类型中.否则,如果为E1 具有带符号类型和非负的 值,且E1×2E2可在 结果类型,那么就是 结果值;otherwise, the behavior is undefined.

编辑:看看C++98论文.它完全没有提到签名类型.所以它仍然是未定义的行为.

右移负片是实现定义的,对吧.为什么?在我看来:实现定义很容易,因为没有截断遗留问题.当你向左移动时,你不仅要说从右边移动了什么,还要说位的睡觉发生了什么,例如,用2的补码表示,这是另一回事.

C++相关问答推荐

为什么信号量为空= 0,而不是阻塞?

找出文件是否包含给定的文件签名

当打印字符串时,为什么在c中没有使用常量限定符时我会收到警告?

将 typewriter LF打印到Windows终端,而不是隐含的CR+LF

如何将字符串argv[]赋给C中的整型数组?

拥有3x3二维数组并访问数组[1][3]等同于数组[2][0]?

为什么即使在强制转换时,此代码也会溢出?

我在这里正确地解释了C操作顺序吗?

如何在C中使printf不刷新标准输出?

Vcpkg的配置文件

在句子中转换单词的问题

如何使用C++在控制台中以彩色打印被阻止的客户端

试图创建一个基本的Word克隆,但遇到了障碍

这段代码用于在C中以相反的顺序打印数组,但它不起作用

有没有办法减少C语言中线程的堆大小?

是否有单独的缓冲区用于读写库调用?

在文件描述符上设置FD_CLOEXEC与将其传递给POSIX_SPOWN_FILE_ACTIONS_ADCLOSE有区别吗?

DennisM.Ritchie的C编程语言一书中关于二进制搜索的代码出现错误?

C struct 中的冒泡排序

当 n 是我们从用户那里获得的整数时,创建 n 个 struct 参数