Для чего вы можете использовать неназванную структуру или объединение?

Я вижу, как

union {
uint32_t ip_address
 struct {
          uint8_t oct1;
          uint8_t oct2;
          uint8_t oct3;
          uint8_t oct4;
        };
};

Может быть полезно кому-то, но struct в примере структуры здесь: Подробности MS-предупреждения C4201 кажутся немного странными. Может ли кто-нибудь продемонстрировать хороший пример использования?

Ответ 1

Безумный union внутри a struct имеет смысл, потому что он позволяет ссылаться на членов союза без указания его имени, следовательно, более короткий код:

struct {
  int a;

  union {
    int b, c, d;
  };
} foo;

Таким образом, доступ к членам union аналогичен доступу к члену содержащейся структуры: foo.a и foo.b. В противном случае вы должны использовать foo.union_name.b для доступа к члену союза.

Конечно, "пользовательский" программист, использующий такую ​​структуру, должен знать, что установка foo.c влияет на значение foo.b и foo.d.

По той же причине можно сделать обратное, а именно поставить анонимный struct внутри union:

union {
  struct {
    int a, b;
  };

  int c;
} foo;

Этот способ foo.a и foo.b можно использовать одновременно, а foo.c можно использовать в другом случае.

Я не могу думать о каких-либо других целях для анонимных структур или союзов. "Объявление" анонимной структуры/объединения является оксюмороном и похоже на выражение int; вместо int a;.

Ответ 2

Это в основном потому, что структура и объединение настолько схожи. В общем случае полезно иметь анонимные структуры внутри союзов и анонимные объединения внутри структур, но вложенные структуры внутри структур или союзов внутри профсоюзов в основном эквивалентны перечислению их членов напрямую.

Обратите внимание, что объединения не должны использоваться для преобразования значений, так как нет никаких гарантий макета.

Ответ 3

Вы можете использовать анонимную структуру в структуре или классе для группировки некоторого значения, которое является простыми старыми данными, чтобы облегчить инициализацию экземпляра (с помощью memset), но не может этого сделать, потому что класс выводится из другого.

Exemple:

#include <string.h>
class Base
{
private:
    int field1;
    int field2;

public:
    Base()
    {
        // initialize field1, field2
    }

    virtual void DoSomething();
};

class Derived : public Base
{
private:
    struct
    {
        int field2;
        int field3;
        int field4;
        // ...
        int field99;
    } data;

public:
    Derived()
    : Base()
    {
        memset(&data, 0, sizeof(data));

        // if you didn't group those value in an anonymous struct
        // you would have to do something like that (not safe):
        // memset(sizeof(Base) + (char*)this, 0, sizeof(Derived) - sizeof(Base));
    }
};

Обратите внимание, что существуют лучшие альтернативы (в моем примере с использованием std::vector или int [99]). Но иногда это может быть полезно.

Ответ 4

В этом случае вы сопоставляете структуру (содержащую 4 байта) и unsigned int (4 байта) в том же месте памяти.