объединение против маскирования битов и сдвига битов

Каковы недостатки использования unions при хранении некоторой информации, например, серии байтов, и возможности доступа к ней сразу или по одному.

Пример: Цвет может быть представлен в RGBA. Таким образом, тип цвета может быть определен как,

typedef unsigned int RGBAColor;

Затем мы можем использовать «сдвиг и маскировку» битов, чтобы «получить или установить» красные, зеленые, синие, альфа-значения объекта RGBAColor (так же, как это делается в функциях Direct3D с помощью макрофункций, таких как: D3DCOLOR_ARGB() ).

Но что, если я использовал союз,

union RGBAColor
{
unsigned int Color;
struct RGBAColorComponents
{
unsigned char Red;
unsigned char Green;
unsigned char Blue;
unsigned char Alpha;
} Component;
};

Тогда мне не нужно будет всегда делать сдвиг (<<) или маскировка (&) для чтения или записи компонентов цвета. Но есть ли проблема с этим? (Я подозреваю, что это имеет некоторые проблемы, потому что я не видел, чтобы кто-нибудь использовал такой метод.)

Может ли Endianness быть проблемой? Если мы всегда используем Component для доступа к цветным компонентам и использования Color для доступа ко всему объекту (для копирования, назначения и т. д. в целом) порядок байтов не должен быть проблемой, верно?

— РЕДАКТИРОВАТЬ —
Я нашел старый пост, который является той же проблемой. Так что я думаю, что этот вопрос — своего рода репост: P извините за это. вот ссылка : Это хорошая практика, чтобы использовать союзы в C ++?

Судя по ответам, кажется, что использование союзов для данного примера нормально в C ++. Поскольку там нет изменения типа данных, есть только два способа получить доступ к одним и тем же данным. Пожалуйста, поправьте меня, если я ошибаюсь. Благодарю. 🙂

3

Решение

Такое использование объединений недопустимо в C ++, где объединение включает перекрывающиеся, но взаимоисключающие объекты. Вы не можете написать одного члена союза, а затем зачитать другого члена.

Это допустимо в C, где это рекомендуемый способ наказания типа.

Это относится к проблеме (строгого) псевдонимов, с которой сталкивается компилятор при попытке определить, различаются ли два объекта с разными типами. Языковые стандарты не согласны, потому что эксперты все еще выясняют, какие гарантии могут быть предоставлены без ущерба для производительности. Лично я избегаю всего этого. Что бы int на самом деле быть использованы для? Безопасный способ перевести это скопировать байты, как memcpy,

Существует также проблема порядка байтов, но имеет ли это значение, зависит от того, что вы хотите сделать с int,

1

Другие решения

Я верю, используя союз решает любые проблемы, связанные с порядком байтов, так как, скорее всего, порядок RGBA определяется в сетевом порядке. Кроме того, тот факт, что каждый компонент будет uint8_t или около того, может помочь некоторым компиляторам использовать расширенную загрузку со знаком / нулем, сохраняя младшие 8 битов непосредственно в не выровненный байтовый указатель и даже будучи в состоянии распараллелить некоторые байтовые операции (например, рука имеет некоторые упакованные 4х8 битная инструкция).

0

По вопросам рекламы [email protected]