Определение порядка байтов

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

Я выбрал «прямой порядок байтов» в качестве соглашения ввода-вывода, что означает, что для ЦП с прямым порядком байтов мне нужно преобразовывать данные во время записи или чтения.

Проблема не в преобразовании. Проблема, с которой я сталкиваюсь, заключается в обнаружении порядка байтов, желательно во время компиляции (поскольку ЦП не меняет порядок байтов в середине выполнения ...).

До сих пор я использовал это:

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
...
#else
...
#endif

Он задокументирован как предопределенный макрос GCC, и Visual, похоже, тоже его понимает.

Однако я получил отчет о том, что проверка не выполняется для некоторых систем big_endian (PowerPC).

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

[Edit]: Большинство предлагаемых решений основаны на «тестах времени выполнения». Эти тесты иногда могут быть правильно оценены компиляторами во время компиляции и, следовательно, не требуют реальной производительности во время выполнения.

Однако ветвления с помощью некоторого вида if (0) {...} else {...} >> недостаточно. В текущей реализации кода объявление переменных и функций зависит от обнаружения big_endian. Их нельзя изменить с помощью оператора if.

Что ж, очевидно, есть запасной вариант, который состоит в том, чтобы переписать код ...

Я бы предпочел избежать этого, но, ну, это похоже на убывающую надежду ...

[Edit 2]: Я протестировал «тесты времени выполнения», глубоко изменив код. Несмотря на то, что они выполняют свою работу правильно, эти тесты также влияют на производительность.

Я ожидал, что, поскольку тесты имеют предсказуемый результат, компилятор сможет исключить плохие ветки. Но, к сожалению, не всегда работает. MSVC - хороший компилятор, успешно устраняющий плохие ветки, но GCC дает смешанные результаты в зависимости от версий, типа тестов и оказывает большее влияние на 64-битные, чем на 32-битные.

Это странно. И это также означает, что компилятор не может гарантировать выполнение тестов во время выполнения.

Edit 3 : В наши дни я использую объединение констант времени компиляции, ожидая, что компилятор решит его до четкого сигнала «да / нет». И работает неплохо: https://godbolt.org/g/DAafKo

18
задан Cyan 18 July 2017 в 22:38
поделиться