++((unsigned)x)的意外结果,x是uint8_t?

Bar*_*art 1 c gcc

为什么这段代码不会导致y == 0x100

uint8_t x = 0xff;
unsigned y = ++((unsigned)x);
Run Code Online (Sandbox Code Playgroud)

请在此处查看:http://codepad.org/dmsmrtsg

AnT*_*AnT 9

您发布的代码在C语言的观点上无效.C中任何强制转换的结果都是右值.它不能用作参数++.运算符++需要左值参数.即表达式++((unsigned) x)在标准C语言中是不可编译的.

在这种情况下,您实际观察到的是GCC的"广义左值"扩展

http://gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Lvalues.html

根据该扩展(与标准C相反),应用于左值的强制转换产生左值.当您尝试将某些内容写入结果"广义"左值时,正在写入的值将被转换两次:首先将其转换为显式强制转换所指定的类型,然后将中间结果再次转换为收件人对象的类型.最终结果将放入收件人对象中.

例如,如果和你x在一起

(unsigned) x = 0x100;
Run Code Online (Sandbox Code Playgroud)

它实际上将被GCC解释为

x = (uint8_t) (unsigned) 0x100;
Run Code Online (Sandbox Code Playgroud)

最终的价值x将是0.

这正是你的例子中发生的事情.在GCC你的

++((unsigned) x)
Run Code Online (Sandbox Code Playgroud)

相当于

(unsigned) x = (unsigned) x + 1;
Run Code Online (Sandbox Code Playgroud)

这又被GCC解释为

x = (uint8_t) (unsigned) ((unsigned) x + 1);
Run Code Online (Sandbox Code Playgroud)

这就是为什么你0x为结果,那就是0那个,然后获取分配给您的y.

此扩展名称被GCC文档弃用.