2017-01-13 17 views
1

Я вполне уверен, что вычитание одного uint8_t из другого должно привести к другому знаку без знака, но некоторые из моих результатов меня смущают.Есть ли разница между унарными и n -

uint8_t a = 2; 
    uint8_t b = 1; 
    uint8_t c = -a; 
    long d = b - a; 
    long e = b + c; 

Когда я получить значение d она производит -1, а e как я ожидал бы 255. Это ошибка с версией gcc Я использую ..... правильно?

Для справки Я использую компилятор arm-none-eabi-g++ для своих MSP-432.

Глядя на this, кажется, указывает, что gcc просто похоже на ошибку.

Глядя на this Вопрос о том, что крест-болт и рука gcc ошибаются.

Что здесь происходит?

+0

используется спецификатор преобразования b «с, пожалуйста? –

+1

В C вы не можете работать с типами, меньшими, чем 'int'. Поиск неявных преобразований. – Olaf

+2

Целочисленные акции как часть арифметических преобразований. Результатом является то, что вы не можете использовать псевдонимы типоразмера для модульной арифметики! Алиасы типа не кодируют ранг конверсии. –

ответ

6

Это ошибка с версией gcc, которую я использую ..... правильно?

Нет, это не так. Что-то, что простое в работе с большим компилятором, вроде gcc, маловероятно.

Что происходит из-за «обычные арифметические преобразования», в частности, «целое продвижение»:

Унарный - способствует a к int, то (int)-2 преобразуется обратно в uint8_t в назначении, получая c == 254 (который является представителем класса эквивалентности -2 в Z mod 2^8, который лежит в [0, 2^8)).

Аналогично, двоичная + и - в строках ниже, которые способствуют int, так что мы в конечном итоге с

d == (int)b - (int)a == (int)1 - (int)2 == -1 

и

e == (int)b + (int)c == (int)1 + (int)254 == 255 

Так что все работает нормально, как это предусмотрено стандартом ,

2

Причины заключается в том, что бинарные операторы проходят интегральное продвижение, прежде чем делать работу, и поскольку int может содержать все возможные значения от uint8_t, используется этот выбор (см http://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_promotion). Таким образом, вычитание выполняется как подписанная операция.

При вычислении e акте запоминания значения в c уже привело к модулю ожидаемого математике, хранения 254, который затем добавляется к значению 1.