инициализация объединения - PullRequest
7 голосов
/ 28 мая 2011

Я пытаюсь глобально инициализировать объединение, как в следующем примере:

#include <cstdio>

typedef union {
    char t[4];
    int i;
} a;

enum {
    w = 5000,
    x,
    y,
    z
};

a temp = {w};
int main() {
    printf("%d %d %d %d %d\n", temp.t[0],temp.t[1],temp.t[2],temp.t[3],temp.i);
    return 0;
}

Однако, если вы запустите код, вы заметите, что ни из temp.i, ни из temp.t [...] на самом деле дать правильный пункт, с которым я инициализировал союз.Я полагаю, этого можно было бы избежать, если бы я мог вручную инициализировать целочисленный член, но, к сожалению, я не могу.Я также не могу изменить порядок элементов в структуре (при изменении порядка int и char все инициализируется должным образом) - они фактически предоставляются внешней библиотекой.Мой вопрос заключается в следующем: как я могу установить целочисленный член структуры глобально , а не член char [4] (или, в данном случае, только первый элемент char [])?

РЕДАКТИРОВАТЬ: Кроме того, есть строго-C ++ решение этой проблемы?то есть тот, где именованная инициализация структуры не работает (потому что он не существует в языке)?

Ответы [ 4 ]

11 голосов
/ 28 мая 2011

В C99 вы можете сделать это:

a temp = { .i=w };
7 голосов
/ 28 мая 2011

В C99 вы можете использовать именованную инициализацию, как в:

a x = { .i = 10 };

Есть некоторые предложения по использованию нестандартного расширения gcc, но я бы избегал этого, если бы кодировал C:

a x = { i : 10 };

Вы можете использовать функцию для инициализации:

inline a initialize( int value ) { // probably choose a better name
   a tmp;
   tmp.i = value;
   return a;
}

и затем используйте:

a x = initialize( 10 );

Компилятор оптимизирует копии.

Если вы используете C ++, вы можете предоставить конструктор для вашего типа объединения:

/*typedef*/ union u {           // typedef is not required in general in C++
    char bytes[sizeof(int)];
    int i;
    u( int i = 0 ) : i(i) {}
} /*u*/;

u x( 5 );
7 голосов
/ 28 мая 2011

Вы хотели бы сделать это:

a temp = {i: w};

Это должно работать как для gcc, так и для g++.

6 голосов
/ 28 мая 2011

Вы можете инициализировать целочисленный член следующим образом:

a temp = {
  .i = w
};
...