【发布时间】:2020-01-13 20:00:56
【问题描述】:
我有这个 C 代码,它试图将 signed short 存储在 signed char 中。
signed char 范围是 [-128,127] 和 signed short 范围是 [-32768, 32767]。
signed char sChar = SCHAR_MAX;
printf("Signed Char: %d", sChar);
signed short sShort = SHRT_MAX;
printf("\nSigned Short: %d", sShort);
sChar = sShort;
printf("\nSigned Short to Signed Char: %d", sChar);
输出:
Signed Char: 127
Signed Short: 32767
Signed Short to Signed Char: -1
我认为这是在后台发生的。
signed short in bits: 0111 1111 1111 1111 (32767)
signed char in bits: <discarded bits> 1111 1111 (-1)
基本上,它从右侧复制所有位并丢弃剩余的位。 TL;DR 将其截短以将其存储在 char 中,因此我们会丢失信息。
问题从这里开始。以上信息是为了提供背景信息。
假设我给signed char -1 并尝试将其存储在signed short 中。 signed short 中的值将是 -1。
如果用二进制表示,它将是:
signed char in bits: 1111 1111 (-1)
signed short in bits: 1111 1111 1111 1111 (32767)
我的问题是编译器如何在后台将 char 分配给 short? 这绝对不是像上面那样的一对一复制。我的猜测是它将位向右移动,而对剩余的位则表示恭维。
1111 1111 // Signed Char
1111 1111 0000 0000 // Shifting bits
1111 1111 1111 1111 // Ones' complimenting the right 8 bits
【问题讨论】:
-
查看汇编代码示例 - godbolt.org/z/UT2PSF
-
第二个是整数提升。
-
有符号溢出未定义;但是,通过假设它不会发生来尝试优化编译器,您会得到这个。实际上,直到最近才定义它,因此大多数供应商都害怕彻底破坏。
-
Out of rage assignment is implementation defined C11 Standard - 6.2.5 Types(p3)