только c++: унарный минус для 0x80000000

Этот вопрос якобы для языковых юристов.

Предположим, что signed и unsigned int имеют ширину 32 бита. Как указано в проекте n3337.pdf, 5.3.1.8,

(-(0x80000000u)) = 0x100000000u-0x80000000u = 0x80000000u

Но не могу найти ответ на вопрос: какой будет унарный минус для signed 0x80000000? Это UB, реализация определена или...?

Вопрос в основном касается расчета во время выполнения.

Сказать

   signed int my_minus(signed int i) { return -i;}
   ....
   int main() {
       signed int a = -0x7FFFFFFF; // a looks like 0x80000001
       signed int b = a - 1;       // b looks like 0x80000000
       std::cout << my_minus(b);
       ....
   }

Тем не менее, ваши комментарии по другим 2 случаям приветствуются:

  • Сворачивание констант времени компиляции, скажем, -(INT_MIN)

  • Вычисление constexpr во время компиляции (если есть разница со свертыванием констант во время компиляции).


(Пожалуйста, посмотрите https://meta.stackexchange.com/questions/123713/is-splitting-a-question-a-good-practice перед голосованием за дубликат. )


person user1123502    schedule 28.02.2012    source источник
comment
Полезно ссылаться на предыдущий вопрос при публикации дополнительных вопросов по той же теме: unary минус для 0x80000000 (со знаком и без знака)   -  person Greg Hewgill    schedule 28.02.2012
comment
@GregHewgill Есть ссылка на meta.stackexchange.com/questions/123713/ (т. е. является ли разделение вопроса хорошей практикой?) и содержит ссылку на мой предыдущий вопрос.   -  person user1123502    schedule 28.02.2012


Ответы (2)


Насколько мне известно, переполнение целого числа со знаком всегда не определено. Из раздела спецификации C++ 5 Expressions, параграф 4:

Если во время вычисления выражения результат не определен математически или не находится в диапазоне представляемых значений для его типа, поведение не определено. [Примечание: большинство существующих реализаций C++ игнорируют целочисленные переполнения. Обработка деления на ноль, формирования остатка с использованием делителя нуля и всех исключений с плавающей запятой различается на разных машинах и обычно настраивается библиотечной функцией. —конечная сноска]

person Carl Norum    schedule 28.02.2012

Знаковые целочисленные типы подчиняются правилам математических целых чисел без добавления компьютерной ерунды. Таким образом, -std::numeric_limits< signed_type >::min() будет поведением undefined, если данный тип не может представлять результирующее число.

В constexpr реализация требуется отклонять это выражение, поскольку все, что вызывает неопределенное поведение, делает константное выражение недействительным, как диагностируемое правило. В этом случае правило является одним из запрещенных пунктов в §5.19,

- результат, который не определен математически или не находится в диапазоне представляемых значений для его типа;

При свертывании констант компилятор, скорее всего, вставит переполненное значение.

person Potatoswatter    schedule 28.02.2012