Когда осознанно нужно достать, например, старший байт из числа размера int, то union точно не нужно - делаем через сдвиги и нормальный компилятор оптимизирует это до адресной арифметики и выгребания конкретного байта (всё это достаточно просто портируется - не зря ведь используются типы uint16_t, uint32_t, там где можно писать unsigned short, unsigned int). Другой случай - имеем отлаженный алгоритм без этих union и вдруг начинается прикручивание какого-либо ввода-вывода - тут, ИМХО, обычно и появляется большинство таких страданий. причём может оказаться, что для записи в архив, например, нужен один порядок байт, а для протокола обмена другой. т.е. я рассматриваю эти преобразования как часть функциональности сериализации (пусть на примитивном уровне) и она не должна входить в первичный отлаженный алгоритм. Преобразование в таком случае пишется явно, что нагляднее, само по себе не дорого как по написанию(не забываем о портировании, выравниваниях, пакетировании и транспортной упаковке по протоколу), так и по скорости работы, да и, IMHO, проще в отладке.