从无符号到有符号的较小类型的位移是否可移植?
我有一个无符号短
(在目标平台上是 16 位)
它包含两个 8 位有符号值,一个在低字节,一个在高字节。
#include <vector>
#include <iostream>
int main() {
unsigned short a = 0xE00E;
signed char b = a & 0xFF;
signed char c = ((a >> 8) & 0xFF);
std::cout << (int)b << std::endl;
std::cout << (int)c << std::endl;
}
这是可移植的,还是我依赖于平台相关的行为?
在所有主要编译器(gcc、msvc、clang)上,结果都是 14
和 -32
,这是预期的输出。
I have a unsigned short
(which is 16 bit on the target platforms)
It contains two 8-bit signed values, one in the lower byte, one in the higher byte.
#include <vector>
#include <iostream>
int main() {
unsigned short a = 0xE00E;
signed char b = a & 0xFF;
signed char c = ((a >> 8) & 0xFF);
std::cout << (int)b << std::endl;
std::cout << (int)c << std::endl;
}
Is this portable, or am I relying on platform dependent behaviour here?
On all major compilers (gcc, msvc, clang), the result is 14
and -32
, which is the expected output.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
免责声明:我不是语言律师
由于没有指定版本,我使用了最后的草案。
那么我们需要检查什么:
unsigned short
能否容纳0xE00E
以及signed char
能否容纳 8 位?a & 0xFF
和((a >> 8) & 0xFF)
转换为signed char
?signed char
如何转换为int
?1.
unsigned long
可以容纳0xE00E
吗?来源:https://eel.is/c++draft/basic.fundamental
2. 如何
a & 0xFF
和((a >> 8) & 0xFF)
转换为signed char
?来源:https://en.cppreference.com/w/cpp/language/implicit_conversion< /a> 积分提升
AFAIU,在
a & 0xFF
、a
可以是int
或unsigned int
。如果
sizeof(unsigned Short) == sizeof(int)
a
将是一个unsigned int
和一个否则。
来源:https://en.cppreference.com/w/c/language/conversion< /a> 常用算术转换
现在我们需要从
int
或unsigned int
转换为signed char
来源:https://eel.is/c++draft/conv.integral# 3
注意:在 C++20 之前是实现定义的(来源 https://en.cppreference.com/w/cpp/language/implicit_conversion)
以及负号的内存表示:
来源:https://eel.is/c++draft/ basic.fundamental#3
一切都好。
已定义以及您的期望。
3、
signed char
如何转化为int
?这是 https://eel.is/c++draft/conv.integral#3再次。并且它不会修改该值。
结论
在 C++20 中
是
在 C++20 之前
无符号到有符号的转换是实现定义的。为了防止这种情况发生,我们需要
并且代码是完全可移植的。
Disclaimer: I am no language lawyer
Since there is no version specified, I used last draft.
So what did we need to check:
unsigned short
hold0xE00E
andsigned char
can hold 8 bits?a & 0xFF
and((a >> 8) & 0xFF)
are transformed intosigned char
?signed char
is transformed intoint
?1. Can
unsigned short
hold0xE00E
?Source : https://eel.is/c++draft/basic.fundamental
2. How
a & 0xFF
and((a >> 8) & 0xFF)
are transformed intosigned char
?Source: https://en.cppreference.com/w/cpp/language/implicit_conversion Integral promotion
AFAIU, in
a & 0xFF
,a
can be anint
orunsigned int
.If
sizeof(unsigned short) == sizeof(int)
a
will be anunsigned int
and anint
otherwise.Source: https://en.cppreference.com/w/c/language/conversion Usual arithmetic conversions
Now we need to go to
signed char
fromint
orunsigned int
Source: https://eel.is/c++draft/conv.integral#3
Note: is implementation-defined until C++20 (source https://en.cppreference.com/w/cpp/language/implicit_conversion)
And the memory representation of an negative signed:
Source: https://eel.is/c++draft/basic.fundamental#3
All good.
Are defined and what you expect.
3. How
signed char
is transformed intoint
?It's https://eel.is/c++draft/conv.integral#3 again. And it wont modified the value.
Conclusion
In C++20
Yes
Before C++20
The conversion unsigned to signed is implementation defined. To prevent this to happen we need to
And the code is fully portable.