только c ++: унарный минус для 0x80000000 - PullRequest
3 голосов
/ 28 февраля 2012

Этот вопрос, предположительно, для языковых юристов.

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

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

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

Вопрос в основном о вычислениях во время выполнения.

Say

   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 перед голосованием за дубликаты.)

Ответы [ 2 ]

4 голосов
/ 28 февраля 2012

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

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

3 голосов
/ 28 февраля 2012

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...