Я не могу найти нигде в стандарте C, который бы оправдал следующее:
int n = -0x80000000 // set n to -2^31
Предположим, что в реализации int - 32 бита. Очевидная проблема заключается в том, что целочисленная константа имеет тип unsigned int, как указано в таблице в проекте стандарта комитета в п. 6.4.4.1, параграф 5. Затем вычисляется отрицание в соответствии с 6.5.3.3 параграф 3:
Результатом унарного оператора - является отрицательное значение его (продвинутого) операнда. Целочисленные рекламные акции выполняются для операнда, и результат имеет повышенный тип.
Выполнение целочисленных рекламных акций не меняет тип (unsigned int остается unsigned int). Потом снимается негатив. Поскольку в результате сохраняется повышенный тип, он сокращается по модулю 2 ^ 32, получая 2 ^ 31 (поэтому отрицание не имеет никакого эффекта).
Назначение значения вне допустимого диапазона для типа int покрывается следующим:
6.3.1.3 Целые числа со знаком и без знака
1 Когда значение с целочисленным типом преобразуется в другой целочисленный тип, отличный от _Bool, если значение может быть представлено новым типом, оно не изменяется.
2 В противном случае, если новый тип является беззнаковым, значение преобразуется путем многократного добавления или вычитания на единицу большего, чем максимальное значение, которое может быть представлено в новом типе, до тех пор, пока значение не окажется в диапазоне нового типа. 60)
3 В противном случае новый тип подписывается и значение не может быть представлено в нем; либо результат определяется реализацией, либо возникает сигнал, определяемый реализацией.
Итак, в конце концов, мы получаем поведение, определяемое реализацией, когда пытаемся присвоить действительное значение int объекту int (при условии, что 2-дополнение без представления ловушки).
Следующее будет стандартным, гарантированно дающим ожидаемый результат:
int n = -(long long)0x80000000 // set n to -2^31
Итак, вам действительно нужно выполнить приведение, чтобы правильно выполнить назначение в диапазоне, или мне что-то не хватает?
int
может быть 16-битным. - person chux - Reinstate Monica   schedule 06.07.2016int n = -0x80000000
не имеет смысла. Если вы напишете действительно странный код, вы также часто будете запускать действительно странное стандартное поведение C. - person Lundin   schedule 06.07.2016implicit conversion
на тип целевой переменной - person user3629249   schedule 07.07.2016