Инициализация соединения в С++ и C
Я создал рабочую библиотеку C, которая использует константы, в заголовочных файлах, определенных как
typedef struct Y {
union {
struct bit_field bits;
uint8_t raw[4];
} X;
} CardInfo;
static const CardInfo Y_CONSTANT = { .raw = {0, 0, 0, 0 } };
Я знаю, что инициализатор .raw
является синтаксисом C.
Как определить константы с объединениями в них таким образом, чтобы я мог использовать их в C и С++.
Ответы
Ответ 1
У меня была та же проблема. Для C89 верно следующее:
С инициализаторами в стиле C89 элементы структуры должны быть инициализированы в заявленный заказ, и только первый член союза может быть инициализируется
Я нашел это объяснение:
Инициализация структур и объединений
Ответ 2
Я считаю, что С++ 11 позволяет писать собственный конструктор так:
union Foo
{
X x;
uint8_t raw[sizeof(X)];
Foo() : raw{} { }
};
Этот параметр по умолчанию инициализирует объединение типа Foo
с активным членом raw
, который имеет все элементы с нулевой инициализацией. (До С++ 11 не было возможности инициализировать массивы, которые не являются полными объектами.)
Ответ 3
Я решил выбрать следующий путь.
- Не используйте инициализацию
.member
.
- do nost использовать
static const struct Foobar
инициализацию членов
Вместо этого объявите глобальную переменную:
extern "C" {
extern const struct Foobar foobar;
}
и инициализировать его в глобальном разделе:
struct Foobar foobar = { 0, 0, 0, 0 };
а вместо того, чтобы прослушивать компилятор С++ с помощью современного синтаксиса ANSI C99, я позволю компоновщику выполнить работу над символами C.
Ответ 4
C89 разрешено для инициализации союзов путем прямого перечисления элемента, который вы хотите инициализировать (например, того, что у вас есть в коде). C99 изменил это так, чтобы вы могли инициализировать его первым элементом.
С++ разрешает эту форму инициализации только первым элементом. Таким образом, это код, который должен хорошо работать для любого случая:
static const CardInfo Y_CONSTANT = {{0, 0, 0, 0 } };