LINUX.ORG.RU

Насколько порочно такое использование union-ов?

 


0

4

По стандарту из union можно писать только то поле, которое было в него записано последним. А если речь идет о структурах?

struct type_a {
  int field1;
  char field2;
};

struct type_b {
  struct type_a a;
  double field3;
};

void do_a(struct type_a *a);
void do_b(struct type_b *b);

typedef union {
  struct type_a a;
  struct type_b b;
} super_type;

/* x->b гарантированно был инициализирован */
void do_c(super_type *x) {
  do_a(&x->a);
  do_b(&x->b);
}

Или вообще вот так (при условии что безымянная структура внутри union-а всегда совпадает с S):

struct S {
  char field1;
  int field2;
};

void do_S(struct S *s);

struct M {
  double x, y;
  union {
    struct {
      char field1;
      int field2;
    };
    struct S s;
  };
};

void do_M(struct M *m)
{
  m->field1 = '5';
  m->field2 = 5;
  do_S(&m->s);
}

Из стандарта C99 (в C89 это в 6.3.2.3):

§ 6.5.2.3 Structure and union members
...
5 One special guarantee is made in order to simplify the use of unions: if a union contains
several structures that share a common initial sequence (see below), and if the union
object currently contains one of these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of the completed type of the union
is visible. Two structures share a common initial sequence if corresponding members
have compatible types (and, for bit-fields, the same widths) for a sequence of one or more
initial members.
Так что, вроде, да, можно.

xaizek ★★★★★
()

Если

/* x->b гарантированно был инициализирован */

то почему

  do_a(&x->a);
  do_b(&x->b);

а не

  do_a(&x->b.a);
  do_b(&x->b);

А так стандарт явно разрешает же обращаться к union через любой член если ты обращаешься только к полям общим для всех членов. Но я вот что-то не могу сказать, являются ли common initial sequence поля type_a и его включение как структуры. Безопаснее предположить что нет.

Fix: я смотрел в C++ стандарт, но если в C

Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.

то таки скорее, всё-таки, да.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.