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