Необязательное действие, сопоставление прег, маршрут PHP [закрыто]

TL; DR

clang верен, это известно gcc. Вы можете использовать intptr_t вместо этого и использовать, когда вам нужно использовать это значение, или если это не работает, то оба gcc и clang поддерживают небольшую задокументированную работу, которая должна разрешить ваш конкретный вариант использования.

Подробности

Итак, clang верна на этом, если мы перейдем к черновому стандарту C ++ 11 5.19 Константные выражения paragraph 2 говорит:

Условное выражение является выражением постоянной константы, если оно не включает одно из следующих значений как потенциально оцененное subexpression [...]

blockquote>

и включает следующую марку:

- reinterpret_cast (5.2.10);

blockquote>

Одним простым решением было бы использовать intptr_t :

static constexpr intptr_t ptr = 0x1;

, а затем использовать позже, когда вам нужно его использовать:

reinterpret_cast(foo::ptr) ;

Возможно, соблазнительно оставить это, но эта история становится интереснее. Это известно и все еще открывает ошибку gcc, см. Ошибка 49171: [C ++ 0x] [constexpr] Константные выражения поддерживают reinterpret_cast . Из обсуждения видно, что у разработчиков gcc есть некоторые явные примеры использования:

Я считаю, что нашел подходящее использование reinterpret_cast в постоянных выражениях, используемых в C ++ 03:

//---------------- struct X {  X* operator&(); };

X x[2];

const bool p = (reinterpret_cast(&reinterpret_cast(x[1]))
- reinterpret_cast(&reinterpret_cast(x[0]))) == sizeof(X);

enum E { e = p }; // e should have a value equal to 1
//----------------

В основном эта программа демонстрирует технику, на основе функции библиотеки адресов C ++ 11 на основе и, исключая reinterpret_cast безоговорочно из постоянных выражений на базовом языке, эта полезная программа недействителен и сделает невозможным объявление addressof как функции constexpr.

blockquote>

, но не смог получить исключение, вырезанное для этих случаев использования, см. закрытые вопросы 1384 :

Хотя reinterpret_cast разрешен в выражениях константы адреса в C ++ 03, это ограничение было реализовано в некоторых компиляторах и не доказало, что оно нарушает значительные количества кода. CWG посчитал, что осложнения, связанные с указателями, чьи изменения изменились (арифметика указателя и разыменование не могли быть разрешены на таких указателях), перевешивали возможную полезность ослабления ограничения тока.

blockquote>

НО , по-видимому, gcc и clang поддерживают небольшое документированное расширение, которое позволяет постоянно складывать непостоянные выражения, используя __ builtin_constant_p (exp) , и поэтому следующие выражения принимаются как gcc и clang:

static constexpr const void* ptr = 
  __builtin_constant_p( reinterpret_cast(0x1) ) ? 
    reinterpret_cast(0x1) : reinterpret_cast(0x1)  ;

Поиск документации для этого почти невозможно, но это llvm commit является информативным со следующими фрагментами, которые содержат интересное чтение:

  • поддерживает gcc __builtin_constant_p ()? ...: ... складной взлом в C ++ 11
blockquote>

и:

+ // __builtin_constant_p? : является магическим и всегда является потенциальной константой.

blockquote>

и:

  • // Этот макрос заставляет свой аргумент быть сложенным, даже если это не
  • // иначе константное выражение.
  • определяет fold (x) (__builtin_constant_p (x)? (x): (x))

blockquote>

Мы можем найти более формальное объяснение этой функции в электронной почте gcc-patches: C постоянные выражения, VLA и т. д. исправления , который гласит: :

Кроме того, правила для __builtin_constant_p, вызываемые как условие условного выражения в реализации, более расслаблены, чем правила в формальной модели: выбранная половина условного выражения полностью свернута без учета того, формально является постоянным выражением, поскольку __builtin_constant_p проверяет полностью сложенный аргумент.

blockquote>

0
задан taratula 25 February 2015 в 14:58
поделиться