Согласно сноске 128 к 2018 году, определяется реализацией, является ли битовое поле, определенное с помощью int
, как в int YWheelSpeed
, подписанным или неподписанным. Поскольку ваша реализация показывает отрицательное значение для него, предположительно, оно подписано, и, следовательно, как 16-разрядное целое число со знаком, оно может представлять значения от −32 768 до 32 767.
Мы также можем вывести, что int
в вашей реализации более 16 бит, вероятно, 32 бита (из-за того, что «65535» печатается в одном случае, когда int y
печатается с «% d»).
Рассмотрим это назначение:
dataOut->fields.YWheelSpeed = (readBuff[33] & 0x00FF) << 8 | (readBuff[32] & 0x00FF);`
В этом выражении readBuff[33]
и readBuff[32]
преобразуются в int
с помощью обычных повышений . 0x00FF
также является int
.
. Если предположить, что readBuff[33]
равно 255, а readBufff[32]
равно 159 (что равно 2 8 -97), то значениевыражение на правой стороне =
составляет 65 439 (то есть 2 16 -97). В присваивании правый операнд преобразуется в тип левого операнда, который представляет собой 16-разрядное целое число со знаком. В этом случае значение 65 439 не может быть представлено 16-разрядным целым числом со знаком. C 2018 6.3.1.3 3 говорит нам, что «либо результат определяется реализацией, либо повышается сигнал, определяемый реализацией».
Обычной реализацией этого преобразования является получение результата по модулю 2 16 или, что то же самое, переосмыслить 16 младших битов int
как 16-разрядное целое число с дополнением до двух. Это дает −97. Поскольку ваша реализация впоследствии показала -97 для значения, вероятно, именно это и сделала ваша реализация.
Таким образом, dataOut->fields.YWheelSpeed
присваивается значение -97. Когда позже оно печатается с:
printf("structure y wheel speed is: %d \n", temp.fields.YWheelSpeed);
, тогда аргументы по умолчанию для аргументов , которые включают обычные целочисленные продвижения, преобразуют temp.fields.YWheelSpeed
из 16-разрядного целого числа со знаком со значением −97в int
со значением −97, и печатается «-97».
В противоположность, предположим, что (readBuff[33] & 0x00FF) << 8 | (readBuff[32] & 0x00FF)
печатается с %d
. Как мы видели выше, значение этого выражения составляет 65 439, поэтому должно быть напечатано «65439».
Вопрос гласит:
Теперь вот что, если я напечатаю (readBuff[27] & 0x00FF) << 8 | (readBuff[26] & 0x00FF)
, что соответствует тому, что было заполнено в переменной скорости колеса Y,… оно печатает максимальное значение беззнакового символа (65 535).
Однако (readBuff[27] & 0x00FF) << 8 | (readBuff[26] & 0x00FF)
не является значением, котороебыл назначен на YWheelSpeed
, который предположительно является «переменной скорости колеса Y». YWheelSpeed
было присвоено из readBuff
элементов 32 и 33, а не 26 и 27. Таким образом, мы не должны удивляться, что вместо 65 439 печатается какое-то другое значение.