Рассмотрим следующий фрагмент кода C:
#include <stdint.h>
uint32_t inc(uint16_t x) {
return x+1;
}
При компиляции с gcc-4.4.3 с флагами -std = c99 -march = core2 -msse4.1 -O2 -pipe -Wall on aчисто система x86_64, она выдает
movzwl %di,%eax
inc %eax
retq
Теперь в C прогнозируется переполнение без знака. Я не очень разбираюсь в сборке x86_64, но насколько я вижу, регистр аргумента 16 бит перемещается в 32 битрегистр, который увеличивается и возвращается.У меня вопрос, а что если x == UINT16_MAX.Произойдет переполнение, и стандарт диктует x + 1 == 0, верно?Однако, учитывая, что% eax является 32-битным регистром, он теперь содержит UINT16_MAX + 1, что неверно.
Это позволяет мне задать один вопрос: существует ли переносимый способ отключить переполнение без знака в C, чтобыкомпилятор может предположить, что верхние биты маленькой переменной, хранящиеся в большом регистре, всегда будут равны 0 (поэтому он не должен их очищать)?Если нет (или если решение синтаксически противно), есть ли способ сделать это хотя бы в GCC?
Большое спасибо за потраченное время.