Допустим, что ваш ужасный босс дает вам следующее задание:Как изменить тип переменной
Написать функцию, которая возвращает второй байт в long
. Ниже приведены требования:
- Используйте следующие функции подписи:
uint8_t second_byte(uint32_t l);
Немного вертел решение, которое приходит на ум:
uint8_t second_byte(uint32_t l)
{
uint8_t b = (l >> 8) & 0xFF;
return b;
}
Boss возвращается с другим требованием
- Не используйте бит-скручивание!
Вы покупаете Boss Voodoo Doll и продолжить:
uint8_t second_byte(uint32_t l)
{
uint8_t b = ((uint8_t*) &l)[1];
return b;
}
Boss чувствует себя властная, руки вниз еще одно требование:
- Не Де-/ссылка !!
Идите и купите руководство по изготовлению бомбы и липкую ленту. После нескольких царапин на голове вы придумали следующую схему:
typedef union {
uint8_t u8[4];
uint16_t u16[2];
uint32_t u32;
} long_u;
uint8_t second_byte(long_u l)
{
uint8_t b = long_u.u8[1];
return b;
}
Чистота и красота. Вы идете к своему боссу и представляете решение.
Boss упоминает первое требование (функция подпись). Вы спорите со своим начальником об этом глупом требовании, бесплодно: вы босс босса передал это требование.
Может ли кто-нибудь подумать о способе «изменить» тип переменной. что-то вроде этого (но код, который компилируется):
uint8_t second_byte(uint32_t l)
{
uint8_t b = ((long_u) l).u8[1];
return b;
}
Под «изменения» я имею в виду писать код, который убеждает компилятор обработать переменную типа T
как тип T'
без создания дополнительных инструкций (как с битами и de-/refrencing)
Оптимизация компилятора ПРИМЕЧАНИЕ. Некоторые компиляторы (например, GCC) могут оптимизировать вышеуказанные попытки кодирования, не добавляя никаких инструкций. некоторые не могут (например, IAR). Я ищу конструкцию языка C, которая не зависит от оптимизации компилятора.
Endianness ПРИМЕЧАНИЕ. Я не хочу сосредотачиваться на проблемах энтианности. просто представьте себе uint32_t
является 4-байтовой структурой
Проще говоря, у меня есть переменная типа T
, связанная с областью в памяти.Я хочу иметь другую переменную типа T'
, связанных с той же самой области без возможных команд-стоимости (де-/refrencing)
Вы понимаете, что «де-реферирование» код должен фактически генерировать _zero_ дополнительные инструкции, если у вас есть приличный компилятор, не так ли? (Попробуйте взглянуть на сгенерированный код сборки, чтобы подтвердить это.) – DaoWen
Весь этот код зависит от конечности машины и ** второго байта в длительном ** термине просто плохо и неоднозначно. – Artur
Ваш босс ужасен, давая вам такой без учета энтузиазма. Думаю, это неважно, так как все в этом вопросе в любом случае бессмысленно в реальном мире. – Lundin