союз против побитового маскирования и разрядной перемены

Что является недостатками использования союзы , храня некоторую информацию как ряд байтов и способности получить доступ к ним сразу или один за другим.

Пример: Цвет может быть представлен в 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;
};

Then I will not be needing to always do the shifting (<<) or masking (&) for reading or writing the color components. But is there problem with this? ( I suspect that this has some problem because I haven't seen anyone using such a method. )

Endianness может Быть broblem? Если мы всегда используем Компонент для доступа к компонентам цвета и используют Цвет для доступа ко всему этому (для копирования, назначения, и т.д. в целом), endianness не должен быть проблемой, правильно?

-- EDIT -- I found an old post which is the same problem. So i guess this question is kinda repost :P sorry for that. here is the link : Is it a good practice to use unions in C++?

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

3
nl ja de

2 ответы

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

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

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

Есть также проблема endianness, но имеет ли это значение, зависит от того, что вы хотите сделать с интервал .

1
добавлено
Эр, нет. Используя союзы, чтобы дать иное толкование данным точное напротив устаревших, это шифровалось в C11 как стандартизация существующей практики. союз {структура foo x; неподписанный y[4];}; в основном новый предпочтенный способ перетасовать биты между типами когда you' ре, слишком хорошее для memcpy() . Строгие правила совмещения имен - то, что вы ломаете, когда вы бросаете указатели вокруг, например, (неподписанный *) &x . И да, я имею в виду "новый" - только, в прошлое десятилетие имеют "достижения" в вызванных проблемах компиляторов для тех, кто нарушает фактические строгие правила совмещения имен.
добавлено автор Dietrich Epp, источник
@Deamonpog: You' ре, нарушающее совершенно другие правила, когда вы делаете это. Don' t делают это. Когда необходимо будет преобразовать указатель от одного типа до другого, используйте бросок вместо этого.
добавлено автор Dietrich Epp, источник
Я уверен, что, получая доступ к неправильному члену союз не против строгих правил совмещения имен. В C это было против различного правила, которое запретило участникам доступа союзов кроме "правильного", но это правило было изменено так, техника действительна, но результаты определяются внедрением.
добавлено автор Dietrich Epp, источник
Насколько C++ затронут, союз , техника - фактический метод выполнения этого, точно потому что (1) это doesn' t ломают строгое совмещение имен (2), другие методы действительно ломают строгое совмещение имен (3), если вы сломаете строгое совмещение имен, то вы, вероятно, столкнетесь с проблемами. Таким образом, предполагая, что вы can' t использование memcpy() и you' ре, не бросая, чтобы неподписанную случайную работу , который является хорошо так или иначе.
добавлено автор Dietrich Epp, источник
@Potatoswatter: Да, that' s, что "де-факто" означает.
добавлено автор Dietrich Epp, источник
@Potatoswatter: Я думаю, что это поворачивает дальше вне темы. Ваш ответ утверждает, что это против строгих правил совмещения имен, когда на самом деле это не против строгих правил совмещения имен. Ваш ответ утверждает, что это поведение удерживается от использования, не ссылаясь, какой стандарт — но это неправильное, неважно, какой стандарт вы выбираете. В C++ технику нельзя назвать "устаревшей", потому что это никогда не было законно для начала. В C, "удержанном от использования", полная противоположность правильного слова, чтобы использовать, так как поведение было UB, но больше не является UB.
добавлено автор Dietrich Epp, источник
Дискуссия о "фактическом" должна была подробно остановиться на теме. Исторически говоря, оба комитета по стандартам рассмотрели его как часть их мандата шифровать существующие методы: у них есть точка зрения, что существующий код более ценен, чем существующие внедрения. Так причина я поднял его, то, потому что я рассматриваю его намного более вероятно, что будущий стандарт C++ пересмотрит союз , уловка определила поведение, и несколько менее вероятно что продавцы компилятора введут оптимизацию, которая вызывает нежеланное поведение. Это не математика, стандарт не существен.
добавлено автор Dietrich Epp, источник
@DietrichEpp вы уверены? Это могло бы отличаться между C11 и C++ 11.
добавлено автор Potatoswatter, источник
@DietrichEpp Это и этот ответ покажите, что совмещение имен союз в порядке в C, не в C++. C++ позволяет memcpy , который эффективно инициализирует объект, прежде чем его жизнь начнется. Но это не разрешает двум объектам одновременно жить в том же самом месте.
добавлено автор Potatoswatter, источник
@DietrichEpp, Если фактическая практика - UB, то это все еще должно измениться. Правила - то, чем они определяются, чтобы быть; популярное мнение doesn' t вопрос.
добавлено автор Potatoswatter, источник
@DietrichEpp спасибо за разъяснение вашего значения. It' s спорный вопрос …
добавлено автор Potatoswatter, источник
Таким образом, если я понимаю правильно, согласно Строгому правилу Совмещения имен, что проблема состоит в том, если я использую указатели в союзе как союз {неподписанный интервал * пи; неподписанная случайная работа * PC;} . И его польза, чтобы использовать союз {неподписанный интервал val; неподписанная случайная работа vals [4];} . (Я didn' t знают об этом Строгом правиле Совмещения имен. Поэтому простите мне. Я читаю эта статья теперь.)
добавлено автор Deamonpog, источник
Спасибо. Я на самом деле использую C++. Так использование этого метода будет хорошо для цветов.:)
добавлено автор Deamonpog, источник

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

0
добавлено
pro.cxx
pro.cxx
3 049 участник(ов)

C/C++ chat 0. Простые вопросы, лабы и о IDE — в чат новичков @supapro 1. Не хамим, не переходим на личности, не вбрасываем утверждения без доказательств 2. No Ads, offtop, flood Объявления о вакансиях и евенты - в лс @AlexFails https://t.me/ProCxx/259155

supapro.cxx
supapro.cxx
1 925 участник(ов)

Чат для тех, кто немного знает C++, простые вопросы по реализации, синтаксису и ide – сюда, а для другого есть: /Главный чат по серьезным вопросам — @ProCxx /Чат по обсуждению всего — @fludpac

C++ Russia
C++ Russia
384 участник(ов)

Сообщество разработчиков C++ в Telegram.

cxx.Дискуссионная
cxx.Дискуссионная
298 участник(ов)

это не двач, общайтесь вежливо; разговор на почти любые темы; Не согласны с баном? В лс @AlexFails, @ivario

C++ для маленьких и тупых
C++ для маленьких и тупых
105 участник(ов)

Лоу левел (по среднему IQ участников) чатик ExtremeCode @extremecode Флудилка @extremecode_rest