2015-02-01 3 views
1

Рассмотрим кодпримитивные операции с короткими целыми числами

int16_t x = 1; 
int16_t y = 1; 

auto v = x + y; 

int16_t w = x + y; 

cout << sizeof(v) << endl << sizeof(w) << endl; 

где я использовал #include <cstdint> для целых чисел фиксированного размера. Выход

4 
2 

Почему размеры V и W различны, и как мне сделать размеры целых быть исправлены во время примитивных операций?

Обратите внимание, что результат для v будет таким же, если я использую 8-разрядный целочисленный тип вместо int16_t.

ответ

1

Как объяснено в http://en.cppreference.com/w/cpp/language/implicit_cast:

Prvalues ​​малых интегральных типов (например, char могут быть превращены в prvalues ​​более крупных интегральных типов (таких, как int) В частности, арифметические операторы не принимают типа меньше. чем int в качестве аргументов и интегральных акций автоматически применяется после именующих к RValue конверсии, если это применимо. Это преобразование всегда сохраняет значение.

[акцент мой; ссылка удалена]

Таким образом, вы не можете делать то, что хотите.

Причина, по которой int16_t w = x + y; работает, заключается в том, что она делает преобразование обратно в int16_t в конце. Из этого же источника:

Если тип адресата подписан, значение не изменяется, если исходное целое число может быть представлено в целевом типе. В противном случае результат определяется реализацией. (Обратите внимание, что это отличается от знакового целого числа арифметического переполнения, которое не определено)

[ссылка удалена]


Отредактировано добавить: То есть, я должен отметить, что не существует никакой реальной причина делать то, что вы хотите. Это правда, что int16_t w = x + y; означает int16_t w = static_cast<int16_t>(static_cast<int>(x) + static_cast<int>(y)); вместо того, чтобы начинать с 16-битного добавления; но результат один и тот же. Единственное различие заключается в том, что если x + y выходит за пределы 16-разрядных целых чисел, то int16_t w = x + y; по-прежнему будет достаточно хорошо себя вести (давая результат, определенный реализацией), потому что сам + не запускает переполнение.