Как работает этот reinterpret_cast? (Перенос C++ на Java)

У меня есть код C++, который я пытаюсь перенести на Java, который выглядит так:

struct foostruct {
    unsigned char aa : 3;
    bool ab : 1;
    unsigned char ba : 3;
    bool bb : 1;
};

static void foo(const unsigned char* buffer, int length)
{

    const unsigned char *end = buffer + length;

    while (buffer < end)
    {
        const foostruct bar = *(reinterpret_cast<const foostruct*>(buffer++));
        //read some values from struct and act accordingly
    }

}

Что делает reinterpret_cast?


person etheros    schedule 14.12.2010    source источник
comment
См. также stackoverflow.com/questions/4805058/   -  person Raedwald    schedule 24.03.2016


Ответы (3)


в основном это говорит о том, что 8 бит, представленные в текущем указателе, должны интерпретироваться как «foostruct».

На мой взгляд, лучше было бы написать так:

const unsigned char aa = *buffer & 0x07;
const bool ab          = (*buffer & 0x08) != 0;
const unsigned char ba = (*buffer & 0x70) >> 4;
const bool bb          = (*buffer & 0x80) != 0;

Я думаю, что тогда гораздо более очевидно, что делается. Я думаю, что вам также может быть проще портировать на Java таким образом...

person Goz    schedule 14.12.2010
comment
Осторожно: сдвиги вправо неверны (сдвиг вправо на 3, 4 и 7 соответственно) «Лучше» спорно... - person Pontus Gagge; 14.12.2010
comment
@Pontus: Вы совершенно правы, я забыл сдвинуть вправо. 2 логических значения НЕ смещены вправо .. они больше, чем (поскольку больше, чем возвращает логическое значение). - person Goz; 14.12.2010
comment
Ах. Исправление исправления: это совместное... Я, как обычно, прочитал то, что ожидал увидеть! - person Pontus Gagge; 14.12.2010
comment
Лучше всегда использовать != 0 для преобразования в логическое значение. С > это довольно запутанно. - person starblue; 14.12.2010
comment
@starblue: Специально для вас я изменил его на !=, но лично я не нахожу его более трудным для чтения, однако это я, как и другие, очевидно, ваша точка зрения понята. - person Goz; 14.12.2010
comment
@Goz: Это не только для звездного синего. Проверяя, не равно ли значение 0, лучше проверять != 0. - person sbi; 14.12.2010

Он делает то, что (const foostruct *)buffer в классическом стиле C сделал бы в худшем случае: говорит C++ игнорировать всю безопасность и что вы действительно знаете, что делаете. В этом случае buffer фактически состоит из foostruct, которые, в свою очередь, представляют собой битовые поля, наложенные на одиночные 8-битные символы. По сути, вы можете сделать то же самое в Java, просто получив байты и самостоятельно выполняя операции сдвига и маски.

person Pontus Gagge    schedule 14.12.2010

у вас есть указатель на unsigned char правильно? Теперь представьте, что биты, на которые указывает указатель, обрабатываются так, как будто это объект типа foostruct. Это то, что делает reinterpret_cast - он переинтерпретирует битовый шаблон, чтобы он был представлением памяти другого типа...

person Armen Tsirunyan    schedule 14.12.2010