Как мне переделать мой код, чтобы избежать предупреждения о левом сдвиге? - PullRequest
0 голосов
/ 13 марта 2020

У меня есть этот метод read, предназначенный для чтения целочисленного типа данных из адреса беззнакового указателя на символ data. Например, если data содержит 0x12, 0x34, 0x56, 0x78, 0x9A, read<int>(1, ptrToMyInt) должен поместить 0x3456789A в ptrToMyInt.

Пример:

class MyClass {
    public:
        MyClass();

        template <typename T> void read(int address, T *dest) {
            size_t size = sizeof(T);

            *dest = 0;

            for (unsigned int i = 0; i < size; i++) {
                *dest <<= 8;
                *dest |= data[address + i];
            }
        }

        static constexpr unsigned char data[] = { 0x12, 0x34, 0x56, 0x78 };
}

Когда я использую этот шаблон на неподписанном Указатель на символ (для согласованности, чтобы избежать использования нескольких методов чтения), он выдает предупреждение, поскольку строка *dest <<= 8; сдвигается больше, чем ширина байта, и компилятор не достаточно умен, чтобы понять, что это происходит только один раз, когда байт уже равен 0.

Например:

MyClass c;

unsigned char x;
c.read(2, &x); // warning: shift count >= width of type
               // should and does put 0x56 into x

Демо

Я хочу переработать этот код, чтобы избежать этого предупреждения, но я могу не вижу простой / элегантный способ переписать его. Как мне переписать этот код?

1 Ответ

1 голос
/ 13 марта 2020

С C ++ 17 вы можете сделать

template <typename T> void read(int address, T *dest) {
    constexpr size_t size = sizeof(T);

    if constexpr (size == 1)
    {
        *dest = data[address];
    } else {
        *dest = 0;

        for (unsigned int i = 0; i < size; i++) {
            *dest <<= 8;
            *dest |= data[address + i];
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...