Назначенные инициализаторы в C99: Как обрабатывать пустые неинициализированные элементы структуры в C11?

Поскольку в C я могу называть членов структуры по имени (myStruct.myMember =), мне было интересно, что я буду делать в C ++ с теми элементами, которые не инициализированы.
Итак, как я понял, C ++ не поддерживает этот тип инициализации:

static struct usb_endpoint_descriptor  fs_source_desc = {
.bLength =      USB_DT_ENDPOINT_SIZE,
.bDescriptorType =  USB_DT_ENDPOINT,
.bmAttributes =     USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize =   __constant_cpu_to_le16 (64),
};

Но когда я использую правильный синтаксис, как мне обрабатывать элементы, которые не инициализированы?
Допустим, я хочу bDescriptorType неинициализированный. Я установил его в NULL?

static struct usb_endpoint_descriptor fs_source_desc = {
USB_DT_ENDPOINT_SIZE,
NULL,
USB_ENDPOINT_XFER_BULK,
__constant_cpu_to_le16 (64)
};

Или в C ++ есть способ инициализировать членов структуры по их именам?

1

Решение

Как мне обрабатывать элементы, которые не инициализированы?

Функция, которую вы описываете, называется назначенные инициализаторы и был представлен в C99. Это не поддерживается C ++. Все члены, которые не инициализированы явно, гарантированно будут установлены в ноль (*).

Может быть, вы не учли это, но то же самое относится и к обычной инициализации структуры. Пример:

typedef struct
{
int a;
int b;
} ab;

ab mystruct = { .a = 1 }; // a is 1, b is guaranteed to be 0
ab mystruct = { 1 };      // a is 1, b is guaranteed to be 0

(Последний пример также верен для C ++.)

Это правило языка является причиной, по которой мы можем инициализировать все элементы в структуре / массиве нулями, набрав:

ab mystruct = { 0 };

потому что это на самом деле означает «установить a к нулю, и пусть тогда все другие элементы будут неявно инициализированы к нулю «.


(*) Формально они инициализируются так, как если бы они имели статическую продолжительность хранения, то есть данные обнуляются, указатели устанавливаются в NULL и т. Д. C11 6.7.9 / 10.

7

Другие решения

Если вы используете C++, затем используйте конструкторы. Инициировать NULL более C-way действительно.

И нет, в C ++ нет стандартного способа использовать именованные параметры (что-то вроде boost::parameters может помочь, но здесь нет необходимости).

Ваш случай может быть что-то вроде

struct usb_endpoint_descriptor
{
usb_endpoint_desctiptor(type bL, type bAttr, type wSize) :
bLength(bL), bAttributes(bAttr), wMaxPacketSize(wSize) {}
type bLength;
type bDescriptorType;
type bmAttributes;
type wMaxPacketSize;
};

Однако не рекомендуется оставлять переменные не инициализированными в C ++.

Итак, если вы используете C структура, вы можете

1) Написать обертку C ++.

2) Написать производный класс.

3) Поле Initialize, которое вы не хотите инициализировать каким-либо значением по умолчанию.

7