Тестирование endianess во время компиляции: правильна ли эта функция constexpr согласно стандарту? - PullRequest
13 голосов
/ 06 февраля 2012

После некоторого поиска способа проверки порядка байтов во время компиляции я нашел следующее решение:

static const int a{1};

constexpr bool is_big_endian()
{
    return *((char*)&(a)) == 1;
}

GCC принимает этот код только в некоторых контекстах, где требуется constexpr:

int b[is_big_endian() ? 12 : 25]; //works
std::array<int, testendian() ? 12 : 25> c;  //fails

Для второго случая GCC говорит error: accessing value of ‘a’ through a ‘char’ glvalue in a constant expression.Я не мог найти ничего в стандарте, который запрещает такие вещи.Может быть, кто-то может уточнить, в каком случае GCC является правильным?

Ответы [ 3 ]

10 голосов
/ 06 февраля 2012

Это то, что я получаю из Clang 3.1 ToT:

ошибка: функция constexpr никогда не выдает постоянное выражение

§5.19 [expr.const]

p1 В некоторых контекстах требуются выражения, которые удовлетворяют дополнительным требованиям, подробно описанным в этом подпункте;другие контексты имеют различную семантику в зависимости от того, удовлетворяет ли выражение этим требованиям. Выражения, которые удовлетворяют этим требованиям, называются константными выражениями .

p2 A условное выражение является основным константным выражением если в качестве потенциально выраженного подвыражения не используется одно из следующих значений:

  • [...]
  • a reinterpret_cast (5.2.10);

Итак, (char*)&(a) оценивается как reinterpret_cast, так как такая функция никогда не является действительной constexpr функцией.

2 голосов
/ 03 апреля 2012

Вы должны изучить Boost.Detail.Endian

Это отображение нескольких архитектур на их порядковый номер (через макросы BOOST_BIG_ENDIAN, BOOST_LITTLE_ENDIAN и BOOST_PDP_ENDIAN).Насколько я знаю, нет фактического способа определения порядка байтов во время компиляции, кроме списка, подобного этому.

Для примера реализации, использующего Boost.Detail.Endian, вы можете увидеть библиотеку IНадеюсь получить отзыв на Boost: https://bitbucket.org/davidstone/endian/ (соответствующий файл - byte_order.hpp, но unsigned.hpp также необходим, если вы хотите просто использовать мою реализацию).

0 голосов
/ 02 ноября 2013

Если N3620 - преобразование порядка байтов в сети реализовано, вы сможете использовать constexpr ntoh для проверки на порядковый номер, но помните, что существуют редкие архитектуры, такие как middleian-endian, и вы никогда не сможете поддерживать всеиз них.

...