Я раньше использовал союзы; сегодня я был встревожен, когда прочитал этот пост и узнал, что этот код
union ARGB
{
uint32_t colour;
struct componentsTag
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} components;
} pixel;
pixel.colour = 0xff040201; // ARGB::colour is the active member from now on
// somewhere down the line, without any edit to pixel
if(pixel.components.a) // accessing the non-active member ARGB::components
на самом деле undefined поведение I.e. чтение из члена объединения, отличного от того, которое недавно было написано, приводит к поведению undefined. Если это не предполагаемое использование профсоюзов, что это такое? Может кто-нибудь объяснить это подробно?
Update:
Я хотел прояснить несколько вещей в ретроспективе.
- Ответ на вопрос одинаков для C и С++; мой невежественный молодой человек отметил его как C и С++.
- После прокрутки по стандарту С++ 11 я не мог окончательно сказать, что он вызывает доступ/проверку члена неактивного профсоюза undefined/unspecified/defined-defined. Все, что я мог найти, было §9.5/1:
Если объединение стандартного макета содержит несколько структур стандартного макета, которые имеют общую начальную последовательность, и если объект этого типа стандартного макета содержит одну из структур стандартного макета, разрешено проверять общий начальный последовательность любых элементов структуры стандартного макета. §9.2/19: Две структуры стандартного компоновки имеют общую начальную последовательность, если соответствующие члены имеют совместимые с макетами типы, и ни один из них не является битовым полем, либо оба являются битовыми полями с одинаковой шириной для последовательности одного или нескольких начальных члены.
- В то время как в C, (C99 TC3 - DR 283), это законно для этого (благодаря Pascal Cuoq для этого). Однако попытка сделать это может по-прежнему приводить к поведению undefined, если чтение значения оказывается недопустимым (так называемое "представление ловушки" ) для типа, который он считывает. В противном случае прочитанное значение определяется реализацией.
-
C89/90 назвал это под неуказанным поведением (Приложение J), а книга K & R указала, что она определена. Цитата из K & R:
Это цель объединения - единственная переменная, которая может законно удерживать любой из нескольких типов. [...] до тех пор, пока использование будет последовательным: тип, который был выбран, должен быть типом, который был недавно сохранен. Ответственность программиста заключается в том, чтобы отслеживать, какой тип в настоящее время хранится в союзе; результаты зависят от реализации, если что-то хранится как один тип и извлекается как другое.
-
Выдержка из Stroustrup TС++ PL (выделение мое)
Использование объединений может быть существенным для совместимости данных [...], иногда неправильно используемых для "преобразования типов".
Прежде всего, этот вопрос (название которого остается неизменным с момента моего запроса) было поставлено с намерением понять цель союзов, а не то, что позволяет стандарт. Использование наследования для повторного использования кода, конечно, допускается стандартом С++, но это не была цель или первоначальное намерение введения наследования как языка С++. Вот почему ответ Андрея по-прежнему остается в качестве принятого.