я сейчас пытаюсь создать исходный код 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