Search code examples
c++cstructureinitializer-list

C++ initializer list with complicated structures


I am working on modifying this C code to work with G++ compiler and I am stuck on this pretty complicated structure. G++ compiler complains "sorry, unimplemented: non-trivial designated initializers not supported". I know a solution which involves writing a constructor but the call to the constructor will be huge and way too confusing.Is there some way to simplify this and refractor it so that it is more readable and g++ compliant.

static const struct {
struct {
    __le32 magic;
    __le32 length;
#ifndef USE_DEPRECATED_DESC_HEAD
    __le32 flags;
#endif
    __le32 fs_count;
    __le32 hs_count;
} __attribute__((packed)) header;
struct {
    struct usb_interface_descriptor intf;
    struct usb_endpoint_descriptor_no_audio svc_in;
    struct usb_endpoint_descriptor_no_audio to_ap;
    struct usb_endpoint_descriptor_no_audio from_ap;
} __attribute__((packed)) fs_descs, hs_descs;
} __attribute__((packed)) descriptors = {
    .header = {
#ifdef USE_DEPRECATED_DESC_HEAD
    .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC),
#else
    .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
    .flags = htole32(FUNCTIONFS_HAS_FS_DESC |
                 FUNCTIONFS_HAS_HS_DESC),
#endif
    .length = htole32(sizeof descriptors),
    .fs_count = htole32(4),
    .hs_count = htole32(4),
},
.fs_descs = {
    .intf = {
        .bLength = sizeof descriptors.fs_descs.intf,
        .bDescriptorType = USB_DT_INTERFACE,
        .bNumEndpoints = 3,
        .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
        .iInterface = 1,
    },
    .svc_in = {
        .bLength = sizeof descriptors.fs_descs.svc_in,
        .bDescriptorType = USB_DT_ENDPOINT,
        .bEndpointAddress = 1 | USB_DIR_IN,
        .bmAttributes = USB_ENDPOINT_XFER_INT,
        .bInterval = 10,
        .wMaxPacketSize = 64
    },
    .to_ap = {
        .bLength = sizeof descriptors.fs_descs.to_ap,
        .bDescriptorType = USB_DT_ENDPOINT,
        .bEndpointAddress = 2 | USB_DIR_IN,
        .bmAttributes = USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize = 64
    },
    .from_ap = {
        .bLength = sizeof descriptors.fs_descs.from_ap,
        .bDescriptorType = USB_DT_ENDPOINT,
        .bEndpointAddress = 3 | USB_DIR_OUT,
        .bmAttributes = USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize = 64
    },
},
.hs_descs = {
    .intf = {
        .bLength = sizeof descriptors.hs_descs.intf,
        .bDescriptorType = USB_DT_INTERFACE,
        .bNumEndpoints = 3,
        .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
        .iInterface = 1,
    },
    .svc_in = {
        .bLength = sizeof descriptors.hs_descs.svc_in,
        .bDescriptorType = USB_DT_ENDPOINT,
        .bEndpointAddress = 1 | USB_DIR_IN,
        .bmAttributes = USB_ENDPOINT_XFER_INT,
        .bInterval = 10,
        .wMaxPacketSize = 512,
    },
    .to_ap = {
        .bLength = sizeof descriptors.hs_descs.to_ap,
        .bDescriptorType = USB_DT_ENDPOINT,
        .bEndpointAddress = 2 | USB_DIR_IN,
        .bmAttributes = USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize = 512,
    },
    .from_ap = {
        .bLength = sizeof descriptors.hs_descs.from_ap,
        .bDescriptorType = USB_DT_ENDPOINT,
        .bEndpointAddress = 3 | USB_DIR_OUT,
        .bmAttributes = USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize = 512,
    },
},
};

Solution

  • static const struct {
        struct {
            __le32 magic;
            __le32 length;
    #ifndef USE_DEPRECATED_DESC_HEAD
            __le32 flags;
    #endif
            __le32 fs_count;
            __le32 hs_count;
        } __attribute__((packed)) header;
    
        struct {
            struct usb_interface_descriptor intf;
            struct usb_endpoint_descriptor_no_audio svc_in;
            struct usb_endpoint_descriptor_no_audio to_ap;
            struct usb_endpoint_descriptor_no_audio from_ap;
        } __attribute__((packed)) fs_descs, hs_descs;
    } __attribute__((packed))
    descriptors =
    {
        // header
        {
            // magic
    #ifdef USE_DEPRECATED_DESC_HEAD
            htole32(FUNCTIONFS_DESCRIPTORS_MAGIC),
    #else
            htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
    #endif
            // length
            htole32(sizeof descriptors),
    
            // flags
    #ifdef USE_DEPRECATED_DESC_HEAD
            htole32(FUNCTIONFS_HAS_FS_DESC |
                             FUNCTIONFS_HAS_HS_DESC),
    #endif
            // fs_count
            htole32(4),
            htole32(4),
        },
        // fs_descs
        {
            // intf
            {
                sizeof descriptors.fs_descs.intf, // bLength
                USB_DT_INTERFACE, // bDescriptorType
                3, // bNumEndpoints
                USB_CLASS_VENDOR_SPEC,// bInterfaceClass
                1, // iInterface
            },
            // svc_in ...
            // and so on...
        }
    };