c++ - 将 int32 转换为 uint32 是无操作的吗?
问题描述
我想在没有任何转换的情况下将 a 的位int32_t
插入到类型uint32_t
中,只是重新解释。以下代码正是我想要的:
int32_t iA = -1;
uint32_t uA = *(uint32_t*)&iA;
但我想知道,我是否可以依靠以下更容易编写的演员来生成相同(或更少)的程序集,理想情况下只是mov
s?(即,它永远不会对其进行“数学运算”,而不会触及底层位。)
int32_t iB = -1;
uint32_t uB = (uint32_t)iB;
assert(uA == uB); // ?
解决方案
在 C++20 之前,有符号整数的表示是实现定义的。但是,即使在 C++20 之前,std::intX_t
也保证有 2s'-complement 表示:
int8_t
,int16_t
,int32_t
,int64_t
- 有符号整数类型,宽度分别为 8、16、32 和 64 位,没有填充位,负值使用 2 的补码(仅在实现直接支持该类型时提供)
当你写
std::int32_t iA = -1;
std::uint32_t uA = *(std::uint32_t*)&iA;
你得到所有位设置的值。该标准规定,如果“类型类似于...一种类型,该类型是与对象的动态类型相对应的有符号或无符号类型”,则允许std::int32_t
通过类型指针进行访问。因此,严格来说,在取消引用指针之前std::uint32_t*
,我们必须确保它std::uint32_t
确实是对应的无符号类型:std::int32_t
static_assert(std::is_same_v<std::make_unsigned_t<std::int32_t>, std::uint32_t>);
当你写
std::int32_t iB = -1;
std::uint32_t uB = (std::uint32_t)iB;
您依赖转换为明确定义并保证产生相同值的无符号类型。
至于组装,两种演员都是无操作的:
std::uint32_t foo() {
std::int32_t iA = -1;
static_assert(std::is_same_v<std::make_unsigned_t<std::int32_t>, std::uint32_t>);
return *(std::uint32_t*)&iA;
}
std::uint32_t bar() {
std::int32_t iB = -1;
return (std::uint32_t)iB;
}
结果:
foo():
mov eax, -1
ret
bar():
mov eax, -1
ret
推荐阅读
- c# - C# 应用程序默认凭据不可用
- excel - 修复标签顺序问题
- ios - React Native 存档错误:无法找到 React Native 文件。确保在您的项目依赖项中安装了“react-native”模块
- arduino - 有没有办法为一个输出找到所有可能的输入?
- kotlin - 如何修复错误“java.lang.IllegalStateException:RecyclerView 不能为空”
- django - 在 Django 中命名基于类的视图有错误的方法吗?
- c# - SQL 中的多个 IN 子句
- javascript - 我的车把模板在渲染时自动终止
- javascript - 滚动页面滚动点击非常高的页面 - 无法正常工作
- python - Tensorflow 客户化培训 - ValueError:变量密集/内核/亚当/不存在?