Кто-нибудь придет и укажет, что это совершенно неправильно по стандартам.
В любом случае, десятичные машины больше не разрешены, и на протяжении веков был только один отрицательный ноль.На практике этих тестов достаточно:
INT_MIN == -INT_MAX && ~0 == 0
, но ваш код не работает по двум причинам.Несмотря на то, что говорится в стандарте, constexprs оцениваются на хосте с использованием правил хоста, и существует архитектура, в которой это происходит сбой во время компиляции.
Попытка отменить ловушку невозможна.~(unsigned)0 == (unsigned)-1
надежно проверяет комплимент 2s, поэтому обратный тест действительно проверяет комплимент *;однако ~0
- единственный способ сгенерировать отрицательный ноль при комплиментах, и любое использование этого значения в качестве числа со знаком может быть перехвачено, поэтому мы не можем проверить его поведение.Даже используя специфичный для платформы код, мы не можем поймать ловушки в constexpr, поэтому forgetaboutit.
*, исключая действительно экзотическую арифметику, но эй
Все используют #define
s для выбора архитектуры.Если вам нужно знать, используйте его.
Если вы передали мне фактически стандартный компилятор жалоб, который привел к ошибке компиляции при прерывании в constexpr и оценивался по правилам целевой платформы, а не по правилам платформы хоста с преобразованными результатами, мыможет сделать это:
target.o: target.c++
$(CXX) -c target.c++ || $(CC) -DTRAP_ZERO -c target.c++
bool has_negativezero() {
#ifndef -DTRAP_ZERO
return INT_MIN == -INT_MAX && ~0 == 0;
#else
return 0;
#endif
}