Есть вопрос по поводу преобразования типов в вычислениях в языке Си. Нашел список правил, по которому осуществляется преобразование:

1. Операнды типа float преобразуются к типу double.
2. Если один операнд long double, то второй преобразуется к этому же типу.
3. Если один операнд double, то второй также преобразуется к типу double.
4. Любые операнды типа char и short преобразуются к типу int.
5. Любые операнды unsigned char или unsigned short преобразуются к типу unsigned int.
6. Если один операнд типа unsigned long, то второй преобразуется к типу unsigned long.
7. Если один операнд типа long, то второй преобразуется к типу long.
8. Если один операнд типа unsigned int, то второй операнд преобразуется к этому же типу.

Таким образом если у нас есть программа:
Код:
char add(char a, char b)
{
   return a+b;
}
Операнды бинарной операции "сложения" должны будут преобразованы к типу int (по правилу 4), затем выполняется сама операция и результат преобразуется к типу char.
Компилятор clang именно так и делает, но при этом генерирует цепочку команд примерно такого вида:
Код:
define i8 test(i8 %a, i8 b)
{
   %ext_a = sext i8 %a to i16            ; знаковое расширение типа
   %ext_b = sext i8 %b to i16            ; знаковое расширение типа
   %add = add i16 a, b
   %trunc = trunc i16 %add to i8        ; усечение типа
   ret i8 %trunc
}
В результате llvm кодогенератор начинает все эти действия честно переводить в код z80, т.е. сложение получается медленное и мучительное - с расширением в 16 битный регистр и сложением через ADD HL,RR))
Конечно это лишь пример и данный код оптимизатор сворачивают в одну 8-битную команду сложения, но есть примеры которые можно в ручную свести к 8-битной арифметике, но оптимизатор этого не делает. Пока встречал это в конструкциях с условиями.
Интересно следуют ли имеющиеся компиляторы Си всем вышеперечисленным правилам преобразования типов.

Также интересно вот что:
Размер переменной типа int в стандарте языка Си не определен. В большинстве систем программирования размер переменной типа int соответствует размеру целого машинного слова. Например, в компиляторах для 16-разрядных процессоров переменная типа int имеет размер 2 байта. В этом случае знаковые значения этой переменной могут лежать в диапазоне от -32768 до 32767.
Т.к. Z80 8-битный процессор, то int должен иметь размер 1 байт или я не прав? Или быть может Z80 какой-то промежуточный вариант, т.к. в наборе команд есть операции и для работы с 16 битными данными (напр. ADD HL,HL)?