В настоящее время я пытаюсь создать исходный код C, который должным образом обрабатывает ввод-вывод независимо от того, в чем состоит конечная система.
Я выбрал "little endian" в качестве своего соглашения о вводе-выводе, что означает, что для большого центрального процессора мне нужно преобразовать данные во время записи или чтения.
Конверсия - это не проблема. Проблема, с которой я сталкиваюсь, заключается в обнаружении достоверности, предпочтительно во время компиляции (поскольку ЦП не меняет континент в середине выполнения...).
До сих пор я использовал это:
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
...
#else
...
#endif
Он задокументирован как предопределенный макрос GCC, и Visual, похоже, тоже это понимает.
Тем не менее, я получил сообщение о том, что проверка не выполняется для некоторых систем big_endian (PowerPC).
Итак, я ищу надежное решение, которое гарантирует, что endianess будет правильно обнаружен, независимо от компилятора и целевой системы. ну, по крайней мере, большинство из них...
[Изменить]: Большинство предлагаемых решений полагаются на "тесты времени выполнения". Иногда эти тесты могут быть правильно оценены компиляторами во время компиляции и, следовательно, не требуют реальной производительности во время выполнения.
Однако разветвление с каким-то << if (0) {... } else {... }
>> недостаточно. В текущей реализации кода, с переменной и функции декларации зависит от big_endian обнаружения. Они не могут быть изменены с помощью оператора if.
Ну, очевидно, есть план возврата, который должен переписать код...
Я бы предпочел избежать этого, но, похоже, это уменьшает надежду...
[Edit 2]: Я проверил "тесты времени выполнения", глубоко изменив код. Хотя они выполняют свою работу правильно, эти тесты также влияют на производительность.
Я ожидал, что, поскольку тесты имеют прогнозируемый результат, компилятор может устранить плохие ветки. Но, к сожалению, он не работает все время. MSVC является хорошим компилятором и успешно устраняет неисправные ветки, но GCC имеет смешанные результаты в зависимости от версий, типов тестов и с большим влиянием на 64 бита, чем на 32 бита.
Это странно. И это также означает, что тесты времени выполнения не могут быть реализованы компилятором.
Редактирование 3: В наши дни я использую объединение констант времени компиляции, ожидая, что компилятор решит его на чистый сигнал да/нет. И это работает очень хорошо: https://godbolt.org/g/DAafKo