为什么uint16_t在这里有所作为?

And*_*eKR 13 c microcontroller integer pic

volatile uint16_t r;
unsigned char poly = 0x07;
unsigned char c = 0;

r = (c << 8) ^ poly;
Run Code Online (Sandbox Code Playgroud)

当在Linux上用gcc编译代码时,r7.
当Microchip C18编译相同的代码时,r0.
为什么?

如果我将其更改为:

volatile uint16_t r;
uint16_t poly = 0x07;
uint16_t c = 0;

r = (c << 8) ^ poly;
Run Code Online (Sandbox Code Playgroud)

r也变成7了C18.

C18手册中有关于整数提升的部分,但我认为这与我的问题无关.无论如何,这里是:

ISO要求所有算术都以int精度或更高精度执行.默认情况下,MPLAB C18将以最大操作数的大小执行算术运算,即使两个操作数都小于int.可以通过-Oi命令行选项来设置ISO强制行为.

erg*_*sys 3

由于c << 8在此编译器中未定义,因此无法预测异或的结果。结果可以是编译器选择的任何结果。

有关未定义行为的介绍,请参阅每个 C 程序员应该了解的关于未定义行为的内容,特别是“超大移位量”部分。

  • @R,标准C将提升为int。这个编译器显然并不像OP所指出的那样。所以这次行动本质上是一个超大的转变,AFAICT。 (2认同)