首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >文字与变量的符号扩展

文字与变量的符号扩展
EN

Stack Overflow用户
提问于 2011-10-25 16:19:59
回答 4查看 286关注 0票数 3

我正在使用gcc 4.4.5,在理解简单无符号值的右移位运算符方面有一些困难……

这个测试

代码语言:javascript
运行
复制
    ASSERT_EQ( 0u, (unsigned long)(0xffffffff) >> (4*8) );

传球。

这个测试

代码语言:javascript
运行
复制
    unsigned long address = 0xffffffff;
    ASSERT_EQ( 0u, address >> (4*8) );

失败:

代码语言:javascript
运行
复制
Value of: address >> (4*8)
   Actual: 4294967295
   Expected: 0u

该变量似乎被视为带符号的值,因此会导致符号扩展。(0xffffffff是十进制的4294967295 )。有人能看出其中的区别吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-10-25 16:27:57

将大于或等于左操作数的位数大小的值移位是未定义的行为(§5.8?1)。(我假设unsigned long距离您的注释有32位,如果您考虑符号扩展,那么0xfffffff是预期的结果。)

尽管如此,可能是ASSERT_EQ所做的某些事情导致了这种差异,因为它在GCC 4.5 with good old assert上运行得很好。

票数 5
EN

Stack Overflow用户

发布于 2011-10-25 16:28:23

我认为这一切都归因于未定义的行为。我认为在按位移位中,如果右操作数大于或等于左操作数中的位数,则结果是未定义的。

票数 3
EN

Stack Overflow用户

发布于 2011-10-25 16:29:05

如果unsigned long是32位,则将其移位32位的行为是未定义的。引用C++ 2003标准:

如果右操作数为负,或者大于或等于提升的左操作数的位数长度,则行为未定义。

显然,编译时和运行时的求值方式是不同的--这是完全有效的,只要它们在定义的情况下产生相同的结果。

(如果系统上的unsigned long大于32位,则不适用。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7886504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档