![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| sQu1rr |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 597 Регистрация: 11.11.2008 Где: london Репутация: 3 Всего: 13 |
||||
|
||||
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
О, Вы правы, действительно:) Надо бы иногда проверять типы... А то как вошло в привычку использовать uint типы, когда нужна точность в байтах, так и использую. -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| DarthTon |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 106 Регистрация: 7.2.2009 Репутация: нет Всего: 6 |
Размер long - 4 байта в винде, но 8 байт в x64 юникс-системах. Поэтому надо внимательно использовать его в кроссплатформенном коде.
|
|||
|
||||
| wowka19 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 285 Регистрация: 30.11.2011 Репутация: нет Всего: нет |
Спасибо. Учел ваши замечания:
1) Функция Crc32() возвращает тип ulong. Повлияет ли это на содержимое uint32_t crc32, если ulong будет больше 4 байт? 2) В последней строке я меняю порядок байт. Делаю я это чисто из практического наблюдения (в hex-редакторе увидел, что порядок не тот и поменял). Отсюда вопрос: этот код будет работать одинаково на всех платформах/компиляторах? Это сообщение отредактировал(а) wowka19 - 31.12.2014, 01:28 |
|||
|
||||
| konshyn |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 295 Регистрация: 19.9.2013 Репутация: нет Всего: нет |
если возвращаемое значение будет больше 2^32 - 1, то в переменную типа uint32_t будет записано обрезанное до 4 байт значение, а так не должно влиять. зачем менять просто так? есть порядок байт little endian и big endian, Вам уже писали выше. если Вы хотите переносимости, то должны решить, в каком порядке хранить байты, т.к. если вы будете просто менять, то в little endian поменяете на big endian и наоборот. И тогда на платформах с разным порядком байт программа из файла будет по-разному считывать значения. Храните, например, все содержимое файла в Big Endian формате, и тогда Вам придется менять порядок байт только на платформах с little endian. -------------------- «Потому что ценность акта действия в этой стране возрастает в несколько раз». |
|||
|
||||
| wowka19 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 285 Регистрация: 30.11.2011 Репутация: нет Всего: нет |
Почитал статью на хабре и не совсем понял.
Для уточнения/закрепления прочитанного:
как я понял код выше уже скомпилированный один раз на одной машине может выдавать разные результаты в зависимости машины на которой выполняется. Так? Как я понял порядок байт задается НЕ на уровне ОС, а глубже/ниже и он неизменен. Так? А конкретно на каком уровне он задается: на уровне прошивки BIOS или это вообще аппаратная причуда CPU? Почему для UTF8 не важен порядок байт, ведь это многобайтная кодировка? И как принято писать код, работающий с бинарными данными, чтобы он работал на любой машине одинаково? Это сообщение отредактировал(а) wowka19 - 2.1.2015, 07:22 |
|||
|
||||
| DarthTon |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 106 Регистрация: 7.2.2009 Репутация: нет Всего: 6 |
Это зависит от ЦП. Вся линейка х86 и х86-64 процессоров little-endian. Есть так же процессоры которые поддерживают оба порядка байт.
В ней каджый байт сам по себе, endianness же влият на порядок байт в цельных машинных словах.
Проверять endianness после прочтения данных, и при необходимости конвертировать в нужный порядок. Однако, если вы не собираетесь запускать свои программы на всях там SPARC, IBM POWER и прочих RISC'ах, этим можно не заморачиваться. |
||||||
|
|||||||
| wowka19 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 285 Регистрация: 30.11.2011 Репутация: нет Всего: нет |
Нет. Я неправильно выразился. Уточню: 1. Как программе самостоятельно определить byte order текущей машины, чтобы потом правильно интерпретировать данные? На ум приходит что-то вроде этого:
Но, подозреваю, что это костыль/велосипед и есть давно принятый де факто стандарт. Как пишите вы? 2. Как менять порядок байт без велосипедостроения? Какие есть устоявшиеся варианты, какие из них самые быстрые? Спасибо за помощь! Это сообщение отредактировал(а) wowka19 - 6.1.2015, 09:05 |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
||||
|
||||
| wowka19 |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 285 Регистрация: 30.11.2011 Репутация: нет Всего: нет |
baldina, спасибо, но стало еще хуже:
1. топовое решение в по вашей ссылке:
Какое-то оно чересчур избыточно. Зачем 4 байта когда и двух хватит? Зачем такая абсурдная инициализация = 0x01020304, разве просто единицы (= 1) не хватит? Да и если позанудствовать, то странно видеть в таком коде uint32_t и char[4] вместе, ведь они не всегда соразмерно, а это может быть критичным. 2. на втором месте такой вариант:
Кажется это то что я искал. На самом деле мне не нужно знать какой порядок на машине, мне подойдет функция вроде htonl/ntohl, скрывающая всю кухню преобразований. Вот только это функции не из стандартной библиотеки, а какие-то юниксовые вроде. Замечу, что я использую Qt. Может в нем есть аналоги htonl/ntohl? 3. Копаясь в этих дебрях наткнулся на такой код:
С асмом вообще не дружу, поэтому спрошу: неужели эта одна строчка меняет порядок на BE если он был LE и ничего не делает если он изначально был BE? Это сообщение отредактировал(а) wowka19 - 6.1.2015, 15:33 |
||||||
|
|||||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
что не соразмерно? на это вам с самого начала намекают. в вики (ссылку я давал раньше) про это тоже есть... для тех кто читает до конца это не стандартная библиотека, но есть на всех платформах (используется для работы с сетью) http://msdn.microsoft.com/ru-ru/library/wi...6(v=vs.85).aspx http://linux.die.net/man/3/htonl |
|||
|
||||
| fish9370 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: -1 Всего: 1 |
в сишном коде в юниксе часто используют примерно такие фокусы: объявление: endian.h
compat.h
пример использования:
код из одного известного крупного проекта Это сообщение отредактировал(а) fish9370 - 7.1.2015, 17:00 -------------------- undefined |
||||||||
|
|||||||||
| DarthTon |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 106 Регистрация: 7.2.2009 Репутация: нет Всего: 6 |
Да, 2 байт действительно хватит, но на скорости исполнения инструкций проверки это не отразится, избыточность тут чисто в коде. uint32_t всегда 4 байта и char всегда 1 байт, это вам не обычный int.
Эта штука гораздо более избыточна чем первый вариант... Однако сама htonl конвертирует любой порядок байт в big endian.
Нет, bswap всегда меняет порядок байт в слове, независимо от исходного порядка.
Эта штука задает порядок статически, на этапе компиляции. ТСу же надо это определять в рантайме. Это сообщение отредактировал(а) DarthTon - 9.1.2015, 01:47 |
||||||||
|
|||||||||
| wowka19 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 285 Регистрация: 30.11.2011 Репутация: нет Всего: нет |
Был уверен, что в Qt есть аналог htonl и нашел его: qToBigEndian().
Но я заглянул в исходник и меня просто поразила реализация.
И она жестко зашита макросом. Т.е. если бинарник запустить на машине с сетевым порядком байт, то все сломается. Отсюда вопрос: почему проверка не на этапе выполнения? Это чересчур смелое допущение разработчиков Qt? Или на десктопных машинах, на которые рассчитан Qt, просто не выпускают CPU с сетевым порядком байт? Интересно, в winsock2.h (mingw) функция htonl тоже не выполняет проверку... Это сообщение отредактировал(а) wowka19 - 13.1.2015, 14:49 |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
потому что порядок байт это свойство процессора. изменить его можно только на процессорах, которые могут по-разному работать (тогда инициализацию порядка байт делает ОС). x86 - это всегда little-endian. программа, скомпилированная под конкретную платформу, уже имеет заданный порядок. qbswap(), как видно из названия, просто меняет порядок на обратный. что касается qToBigEndian(), то её несколько вариантов (по результату условной компиляции), например
см. также http://www.ibm.com/developerworks/ru/library/au-endianc/ |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |