?

Log in

No account? Create an account
знаковый или беззнаковый? - По делам сюда приплыл, а не за этим [entries|archive|friends|userinfo]
Anatoly Vorobey

[ website | Website ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Links
[Links:| English-language weblog ]

знаковый или беззнаковый? [фев. 22, 2018|12:50 pm]
Anatoly Vorobey
[Tags|]

(эта запись может быть интересна программистам, знающим C/C++)

Во внутреннем форуме на работе кто-то устроил опрос, который просто не могу не украсть:

Опрос #2078582 unsigned short

"foo" is an "unsigned short". Is the expression "foo + foo" signed or unsigned?

signed
36(17.2%)
unsigned
126(60.3%)
implementation defined
47(22.5%)


Не смотрите в комментарии перед голосованием, там можно обсуждать правильный ответ.
СсылкаОтветить

Comments:
[User Picture]From: mopexod
2018-02-22 11:22 am
Integral Promotions
The difference between the ANSI C and traditional versions of the conversion rules is that the traditional C rules emphasize preservation of the (un)signedness of a quantity, while ANSI C rules emphasize preservation of its value.

In traditional C, operands of types char, unsigned char, and unsigned short are converted to unsigned int. Operands of types signed char and short are converted to int.

ANSI C converts all char and short operands, whether signed or unsigned, to int. Only operands of type unsigned int , unsigned long, and unsigned long long may remain unsigned.

Мило.
(Ответить) (Thread)
[User Picture]From: vladimir000
2018-02-22 11:25 am
Это в предположении, что int != short. Если int == short, то получим unsigned int, иначе - Int.

И не говорите, что 16-битных приложений не бывает:)
(Ответить) (Parent) (Thread)
[User Picture]From: mopexod
2018-02-22 11:27 am
Ну, так вообще супер.
(Ответить) (Parent) (Thread)
[User Picture]From: avva
2018-02-22 12:14 pm
Ага, и поэтому правильный ответ - implementation defined.
(Ответить) (Parent) (Thread)
[User Picture]From: leonov
2018-02-22 12:01 pm
Integral promotions и integral conversions проводятся не по желанию левой пятки компилятора, а лишь если результат выражения необходимо использовать в ситуации, требующей другой тип. Т.е. в данном случае - если результат нужно было бы передать функции f(int). Или если бы результат участвовал в арифметическом выражении с операндом другого типа.

Так что висящее в воздухе выражение foo + foo все-таки имеет тип unsigned short.
(Ответить) (Parent) (Thread)
[User Picture]From: avva
2018-02-22 12:14 pm
Нет, по стандарту они переводятся при любой арифметической операции, вне зависимости от того, что будет происходить с ее результатом.
(Ответить) (Parent) (Thread)
[User Picture]From: leonov
2018-02-22 12:20 pm
Лишь в случае операндов разного типа. Иначе не имело бы смысл различие в реализации переполнения для знаковых и беззнаковых типов:

Overflows
Unsigned integer arithmetic is always performed modulo 2^n where n is the number of bits in that particular integer. E.g. for unsigned int, adding one to UINT_MAX gives ​0​, and subtracting one from ​0​ gives UINT_MAX.
When signed integer arithmetic operation overflows (the result does not fit in the result type), the behavior is undefined: it may wrap around according to the rules of the representation (typically 2's complement), it may trap on some platforms or due to compiler options (e.g. -ftrapv in GCC and Clang), or may be completely optimized out by the compiler.

http://en.cppreference.com/w/cpp/language/operator_arithmetic#Conversions

Edited at 2018-02-22 12:27 (UTC)
(Ответить) (Parent) (Thread)
From: (Anonymous)
2018-02-22 01:57 pm
Вы не туда смотрите.
Начните отсюда https://ideone.com/sT7pg0 а потом ищите объяснение этому.
(Ответить) (Parent) (Thread)