Вытаскивая слова на 32 бита из 64-разрядных значений в C/C++ и не вызывая беспокойство о порядке байтов

Это - мое понимание, которые в побитовых операторах C/C++, как предполагается, независимый порядок байтов и ведут себя способ, которым Вы ожидаете. Я хочу удостовериться, что я действительно получаю старшие значащие и младшие значащие слова из 64-разрядного значения и не волнуюсь о порядке байтов машины. Вот пример:

uint64_t temp;
uint32_t msw, lsw;
msw = (temp & 0xFFFFFFFF00000000) >> 32;
lsw = temp & 0x00000000FFFFFFFF;

Это будет работать?

10
задан Jay Atkinson 3 February 2010 в 18:21
поделиться

8 ответов

Я также использую отдельные модели ракурсов для ввода [GET] и вывода [POST], если только две модели не идентичны. IMHO этот подход является более чистым, проще в обслуживании и более четко выражает, какие данные будут обновлены с помощью данного действия контроллера.

Существует стоимость в терминах LOC, но дополнительный код обычно не логика . В большинстве случаев я не чувствую, что дублирование некоторых автоматических свойств на двух объектах нарушает принцип DRY, и я думаю, что затраты оправданы, чтобы следовать SRP.

Другая стоимость, как вы отметили, заключается в том, что встроенные сильно типизированные помощники не работают так хорошо. Вы думали о том, чтобы писать своих помощников, которые поддерживают ваш образец? Например, можно перегрузить один из существующих помощников, чтобы можно было указать как источник (например, свойство входной модели), так и назначение (например, имя поля формы, которое разносится в выходную модель).

-121--4407662-

Трудно ответить на вопрос, не зная, какие существуют ограничения? У вас есть разрешения на установку? Также большинство систем отслеживания ошибок требуют какой-то поддержки базы данных.

У меня есть предложение. Вы можете установить базовую систему отслеживания ошибок, которая просто позволяет людям создавать билеты, и позволяет вам/кому-то еще закрыть ее.

Здесь упоминаются дополнительные инструменты на базе Windows Хорошее программное обеспечение для отслеживания ошибок/проблем с открытым исходным кодом для Windows

Причина, по которой именно колдфузия?

-121--5086200-

6,5,7 Операторы побитового сдвига

4 Результат E1 < < E2 E1 сдвинутые влево положения E2 разрядов; освобожденный биты заполняются нулями. Если E1 имеет неподписанный тип, значение результат E1 × 2E2, уменьшенный по модулю 1 больше максимального значения представляется в виде результата. Если E1 имеет тип со знаком и неотрицательный значение, и E1 × 2E2 является представимым в типе результата, то есть результирующее значение; в противном случае, поведение не определено.

Так, да, гурантед по стандарту.

17
ответ дан 3 December 2019 в 15:51
поделиться

Да. Должно сработать.

2
ответ дан 3 December 2019 в 15:51
поделиться

Я хотел бы поделиться одной мыслью. Возможно, вам удастся обойти порядок байтов значения, используя функции или макросы, найденные в , чтобы преобразовать порядок сети в хост и наоборот, можно сказать, что он больше используется в сочетании с сокетами, но его можно использовать для этого экземпляра, чтобы гарантировать, что значение, такое как 0xABCD от другого процессора, по-прежнему равно 0xABCD на Intel x86, вместо того, чтобы прибегать к вручную написанным пользовательским функциям для работы с архитектурой с порядком байтов ...?!

Edit: Вот статья о Endianess в CodeProject , и автор разработал макросы для работы с 64-битными значениями.

Надеюсь, это поможет, С уважением, Том.

1
ответ дан 3 December 2019 в 15:51
поделиться

Я думаю, что то, что вы говорите, совершенно верно, но к чему это вас приведет?

Если у вас есть какие-то буквальные значения, то вы знаете, какой конец какой. Но если вы обнаружите, что значения пришли извне программы, вы не можете быть уверены, если они не были каким-то образом закодированы.

0
ответ дан 3 December 2019 в 15:51
поделиться

Эндианство заключается в раскладке памяти. Смещение - о битах (и компоновке битов). Значение слова - о раскладке битов, а не о раскладке памяти. Таким образом, эндианность не имеет ничего общего со значением слова.

1
ответ дан 3 December 2019 в 15:51
поделиться

Да, это должно сработать. Когда вы извлекаете msw, ваша маска на самом деле не дает многого - биты, которые вы маскируете до нуля, будут отброшены, когда вы все равно выполните сдвиг. Лично я, вероятно, использовал бы что-то вроде этого:

uint32_t lsw = -1, msw = -1;
lsw &= temp;
msw &= temp >> 32;

Конечно, для получения значимого результата необходимо инициализировать temp , чего не было в вашем коде.

3
ответ дан 3 December 2019 в 15:51
поделиться

Это сработает, но странная склонность некоторых авторов делать битовую маскировку перед сменой битов всегда озадачивала меня.

На мой взгляд, гораздо более элегантным подходом был бы тот, который делает сдвиг первым

msw = (temp >> 32) & 0xFFFFFFFF; 
lsw = temp & 0xFFFFFFFF; 

хотя бы потому, что каждый раз использует одну и ту же "волшебную" константу битовой маски.

Теперь, если ваш целевой тип беззнаковый и уже имеет желаемую ширину бита, маскировка становится совершенно ненужной

msw = temp >> 32; 
lsw = temp; 
3
ответ дан 3 December 2019 в 15:51
поделиться

В дополнение к другим ответам я добавлю, что вам не следует беспокоиться о порядке байтов в C. Проблема с порядком следования байтов возникает только при просмотре некоторых байтов с типом, отличным от того, который использовался для записи этих байтов изначально. Когда вы это делаете, вы очень близки к проблемам с псевдонимом, что означает, что ваш код может сломаться при использовании другого компилятора или другого флага оптимизации.

До тех пор, пока вы не пытаетесь выполнять такие обращения с обратным типом, ваш код должен быть нейтральным по порядку байтов и безупречно работать как с прямым, так и с прямым порядком байтов. Или, другими словами, если у вас есть проблемы с порядком следования байтов, то поблизости также таятся другие более серьезные проблемы.

0
ответ дан 3 December 2019 в 15:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: