У сдвига битов выше есть ошибка:
unsigned short p = (packetBuffer[1] << 8) | packetBuffer[2];
, если packetBuffer
в байтах (ширина 8 бит), то вышеупомянутый сдвиг может и превратит packetBuffer
в ноль, оставляя вам только packetBuffer[2];
Несмотря на это, это все еще предпочтительнее указателей. Чтобы избежать вышеупомянутой проблемы, я трачу несколько строк кода (кроме довольно-буквально-нулевой оптимизации), это приводит к тому же машинному коду:
unsigned short p;
p = packetBuffer[1]; p <<= 8; p |= packetBuffer[2];
Или сохранить некоторые тактовые циклы и не сдвигать биты с конца:
unsigned short p;
p = (((unsigned short)packetBuffer[1])<<8) | packetBuffer[2];
Вы должны быть осторожны с указателями, оптимизатор укусит вас, а также выравнивания памяти и длинный список других проблем. Да, все сделано правильно, это быстрее, неправильно, ошибка может продолжаться долго и наносить удары по мере необходимости.
Скажем, вы были ленивы и хотели сделать 16-битную математику для 8-битного массива. (немного порядковый номер)
unsigned short *s;
unsigned char b[10];
s=(unsigned short *)&b[0];
if(b[0]&7)
{
*s = *s+8;
*s &= ~7;
}
do_something_With(b);
*s=*s+8;
do_something_With(b);
*s=*s+8;
do_something_With(b);
Нет гарантии, что совершенно безошибочный компилятор создаст ожидаемый код. Массив байтов b
, отправляемый в функцию do_something_with()
, никогда не может быть изменен операциями *s
. Ничто в приведенном выше коде не говорит, что это должно. Если вы не оптимизируете свой код, вы можете никогда не увидеть эту проблему (пока кто-то не оптимизирует или не изменит компиляторы или версии компиляторов). Если вы используете отладчик, вы можете никогда не увидеть эту проблему (пока не станет слишком поздно).
Компилятор не видит связи между s и b, это два совершенно разных элемента. Оптимизатор может предпочесть не записывать *s
обратно в память, поскольку он видит, что *s
имеет ряд операций, поэтому он может сохранить это значение в регистре и сохранить его в памяти только в конце (если когда-либо).
Существует три основных способа решения проблемы с указателем выше:
- Объявить
s
летучим.
- Используйте союз.
- Используйте функцию или функции при смене типа.