Цитирование отрицательного целого числа с большим целым без знака
Я столкнулся с кодом, который выполняет следующее преобразование:
static_cast<unsigned long>(-1)
Насколько я могу судить, стандарт С++ определяет, что происходит при преобразовании знакового целочисленного значения в неподписанный тип интеграла (см. Что произойдет, если я присвою отрицательное значение неподписанная переменная?).
В вышеприведенном коде есть озабоченность тем, что типы источника и назначения могут быть разных размеров и зависит от того, влияет ли это на результат. Будет ли компилятор увеличивать тип исходного значения до кастинга? Вместо этого вместо этого будет применено целое число без знака того же размера, а затем увеличьте это? Или что-то еще?
Чтобы уточнить код,
int nInt = -1;
long nLong = -1; // assume sizeof(long) > sizeof(int)
unsigned long res1 = static_cast<unsigned long>(nInt)
unsigned long res2 = static_cast<unsigned long>(nLong);
assert(res1 == res2); // ???
В принципе, я должен беспокоиться о написании кода, например
static_cast<unsigned long>(-1L)
над
static_cast<unsigned long>(-1)
Ответы
Ответ 1
Из стандарта С++ 11, 4.7 "Интегральные преобразования", параграф 2:
Если тип назначения не указан, результирующее значение является наименьшим беззнаковое целое, совпадающее с целым числом источника (по модулю 2 n где n - количество бит, используемых для представления неподписанного типа).
Другими словами, при преобразовании в целое число без знака имеет значение только значение ввода, а не его тип. Преобразование -1 в n-разрядное целое без знака всегда даст вам 2 n -1, независимо от того, какой целочисленный тип -1 начался как.
Ответ 2
Это хороший вопрос и проект С++ standard в этом разделе 4.7
Интегральные преобразования, в которых говорится:
Если тип назначения не указан, результирующее значение представляет собой наименьшее целое без знака, сравнимое с исходным целым (по модулю 2 n где n - количество бит, используемых для представления неподписанного типа). [...]
не является самым прямым для интерпретации, в этом случае я вернусь к черновику стандарта C99, в котором говорится:
В противном случае, если новый тип без знака, значение преобразуется путем многократного добавления или вычитая одно больше максимального значения, которое может быть представлено в новом типе пока значение не окажется в диапазоне нового типа. 49
где сноска 49
с благодарностью говорит:
Правила описывают арифметику по математическому значению, а не значение данного типа выражения.
Это более прямолинейно и явно дает нам результат как -1 + MAX + 1
, который MAX
, независимо от того, какой тип операнда есть.