首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按位运算是否在有符号的固定宽度整数上定义和可移植?

按位运算是否在有符号的固定宽度整数上定义和可移植?
EN

Stack Overflow用户
提问于 2020-04-24 14:02:17
回答 1查看 113关注 0票数 2

我的理解是,对于普通ol的短/int/long类型的某些按位运算,要么依赖于实现,要么是未定义的( << )。

然而,C99引入了固定宽度的整数类型,并显式地将它们定义为两个完全补位,没有填充位。

这是否意味着所有按位操作对于那些提供这些操作的平台来说都是定义良好的和可移植的?

例如,这可以在我的机器™上工作,但是它能保证工作吗?

代码语言:javascript
运行
复制
#include <inttypes.h>
#include <stdio.h>

int main() {
  uint16_t a = 0xffff;
  int16_t b = *(int16_t*)(&a);

  printf("%" PRId16 "\n", b);

  // Prints '-1'

  b <<= 4;

  printf("%" PRId16 "\n", b); 

  // Prints '-16'

  return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2020-04-24 14:14:44

使用固定宽度类型不能保证不受与位移位相关的未定义行为的保护。C标准中关于确切宽度整数类型的7.20.1.1节指出:

1类型胡枝子名称intN_t指定一个带符号整数类型,其宽度为N,没有填充位,并指定两个补码表示形式。因此,int8_t表示这种宽度正好为8位的带符号整数类型。 2类型胡枝子名称uintN_t指定宽度为N且没有填充位的无符号整数类型。因此,uint24_t表示这种宽度正好为24位的无符号整数类型。 3这些类型是可选的。但是,如果实现提供宽度为8、16、32或64位的整数类型,没有填充位,并且(对于有符号类型)具有两个补码表示形式的整数类型,则它将定义相应的typedef名称。

这里没有提到关于这些类型上的位移位操作行为的特殊处理。

这里的一个重要方面是整数提升。对于小于int的固定宽度类型,首先将它们提升为int (而不是int16_tint32_t),然后再应用于大多数操作数。然后你处理的是潜在的未定义的行为。

例如,假设32位int,此代码显示未定义的行为:

代码语言:javascript
运行
复制
uint24_t x = 0xffffff;
uint24_t y = x << 8;

因为在表达式x << 8中,x的值被提升为int,因此移位会导致将位移到该值的符号位中。

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

https://stackoverflow.com/questions/61410204

复制
相关文章

相似问题

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