为什么这段代码不会导致y == 0x100
?
uint8_t x = 0xff;
unsigned y = ++((unsigned)x);
请在此处查看:http://codepad.org/dmsmrtsg
答案 0 :(得分:9)
您发布的代码在C语言的观点上无效。 C中任何强制转换的结果都是右值。它不能用作++
的参数。运算符++
需要左值参数。即表达式++((unsigned) x)
在标准C语言中是不可编译的。
在这种情况下,您实际观察到的是GCC的“广义左值”扩展
http://gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Lvalues.html
根据该扩展(与标准C相反),应用于左值的强制转换产生左值。当您尝试将某些内容写入结果“广义”左值时,正在写入的值将转换为两次:首先将其转换为显式强制转换所指定的类型,然后再次转换中间结果到收件人对象的类型。最终结果将放入收件人对象中。
例如,如果您使用x
(unsigned) x = 0x100;
它实际上将由GCC解释为
x = (uint8_t) (unsigned) 0x100;
,x
的最终值为0
。
这正是你的例子中发生的事情。在GCC你的
++((unsigned) x)
相当于
(unsigned) x = (unsigned) x + 1;
又由GCC解释为
x = (uint8_t) (unsigned) ((unsigned) x + 1);
这就是您在0
中获得x
作为结果的原因,那就是0
然后被分配给您的y
。
此扩展程序被GCC文档称为已弃用。
答案 1 :(得分:1)
要开始这不是有效的C代码,我不知道你是如何编译的,但是你的链接确实显示了一个输出,所以我将尝试根据这个 major <来解释发生了什么/ strong>假设:
我想使用这一行unsigned y = ++((unsigned x));
,你的编译器会删除第二个unsigned
,因此你可以构建它。
所以,假设......
uint8_t x = 0xff; // 8 bit value, max is 255(10) or 0xFF(16)
unsigned y = ++((unsigned)x);
现在x
已经为其类型提供了最大值。您想知道为什么如果我们通过++
+1,y
没有获得0x100
的值。
x
是8位,类型转换它并没有改变它是8位的事实。所以当我们说:
++x
我们正在递增x
(x=x+1
)。所以我们有一个无符号的8位值,最大值并加1,现在它被包围到0.所以y
将得到0.
如果你想要这个,你可以做类似的事情:
int main(void)
{
unsigned char x = 0xFF; //I'm using char because it's 8 bit too
unsigned int y = 1+x; //no need to typecast, we're already unsigned
printf("%#x %#x\n", x, y);
return 0;
}
现在,您将获得预期值(x==0xFF
和y==0x100
)
答案 2 :(得分:0)
试试这个:
uint8_t x = 0xff;
unsigned y = ((unsigned)x) + 1;
它会按照您的预期出现,因为(unsigned) x
现在是双字节值0x0100
。
现在试试这个:
uint8_t x = 0xff;
++x;
0xff
的值包围0x00
。
答案 3 :(得分:0)
我在您的摘录中添加了一些透明度代码,它解释了所有内容。
#include <stdio.h>
#include <stdint.h> // not needed
int main(void) {
uint8_t x = 0xff;
printf("%d\n", sizeof(x));
unsigned y = ++((unsigned)x);
printf("%d\n", sizeof(y));
printf("0x%x\n", y);
printf("%d\n", sizeof(y));
return 0;
}
,输出
1 // size of x
4 // size of y before computation
0x100 // computed value of y from your code
4 // size of y after computation
首先要注意的是sizeof(y)
在计算中保持不变
从输出中,
uint8_t
= 1个字节unsigned
= 4个字节当你在C中进行强制转换时,将其视为对realloc
的隐式调用,其中说:“从块中获取此数据,将其在内存中的大小增加(或减少)到大小为I想要将其转换为,然后在新块中返回相同的数据。
根据我们的大小,unsigned
将有足够的空间来容纳来自单字节操作的计算结果。
以字节级细节重新解释您的代码,
x = 11111111 = 0xff (in a byte)
(unsigned)x = 00000000000000000000000011111111 = 0xff (in a word)
++((unsigned)x) = 00000000000000000000000100000000 = 0x100