допустима потеря эффиктивности. Можно, например, попробовать использовать битовые поля, но вроде как они являются беззнаковыми числами. Можно, например, воспользоваься структурами, в которых оба члена структуры являются данными со знаком:
typedef struct { int i16; signed char i8; } int24;
Но в данном случае придется написать соответствующие подпрограммы для выполнения арифметических операций. Но, опять же, процедура обращения к таким подпрограммам сведет на нет весь выигрыш.