Почему здесь uint16_t имеет значение?
volatile uint16_t r;
unsigned char poly = 0x07;
unsigned char c = 0;
r = (c << 8) ^ poly;
Когда код скомпилирован с gcc в Linux, r
есть 7
.
Когда тот же код скомпилирован Microchip C18, r
- 0
.
Почему?
Если я изменил его на:
volatile uint16_t r;
uint16_t poly = 0x07;
uint16_t c = 0;
r = (c << 8) ^ poly;
r
также становится 7
в C18.
В руководстве C18 есть раздел о продвижении по целому ряду, но я не думаю, что он имеет какое-то отношение к моему вопросу. Во всяком случае, вот оно:
ISO обязывает, чтобы вся арифметика выполнялась с точностью до или более. По умолчанию MPLAB C18 будет выполнять арифметика с размером наибольшего операнд, даже если оба операнда меньше, чем int. Утвержденный ISO поведение может быть введено через -Oi командной строки.
Ответы
Ответ 1
Так как c << 8
undefined в этом компиляторе, результат xor не может быть предсказан. Результатом может быть все, что выбирает компилятор.
См. Что должен знать каждый программист C о undefined Поведение для ознакомления с поведением undefined, особенно в разделе "Негабаритные суммы сдвига" ".
Ответ 2
c < 8 с c a char в основном передает все биты в забвение. Как указано в документе, оба c и 8 соответствуют char, поэтому все делается с помощью char.
c < 8UL может изменить сделку.