2009-12-11 9 views
5

У меня есть-структуру:Возможно ли (юридическое) присвоить анонимный союз в составном литерале?

typedef struct _n 
{ 
    int type; 
    union { 
     char *s; 
     int i; 
    }; 
} n; 

При попытке присвоить соединение буквальным, как:

node n1 = {1, 0}; 
node n2 = {2, "test"}; 

НКУ дает мне некоторые предупреждения, такие как:

warning: initialization makes pointer from integer without a cast 
warning: initialization from incompatible pointer type 

Ну, это ясно, что компилятор не уверен, что я просто назначаю значение, возможно, двусмысленному типу. Тем не менее, даже если я попытаюсь более точно указать:

node n0 = {type: 1, i: 4}; 

я получаю:

error: unknown field ‘i’ specified in initializer 

Я прочитал, что если я ставлю перед тем (union <union name>)i:, то он может работать. Тем не менее, я предпочитаю иметь анонимный союз. Есть ли способ сделать это?

ответ

7

Анонимные союзы не являются стандартными C - они являются расширением для компилятора. Я бы настоятельно рекомендовал дать профсоюзу имя. Если вы настаиваете на использование анонимного объединения, то вы можете дать только инициализатор для первого элемента этого:

node n0 = {1, 0}; // initializes `s' to 0 

При компиляции с -Wall -Wextra -pedantic, НКА дала мне предупреждение «недостающее скобки вокруг инициализатора», который является действительное предупреждение. Инициализатором фактически должно быть определены следующим образом:

node n0 = {1, {0}}; // initializes `s' to 0 

Теперь это только дает предупреждение, что «ISO C не поддерживает неназванные структуры/объединения».

Если вы даете профсоюзу имя, то вы можете использовать функцию C99 под названием назначенных Инициализаторов для инициализации конкретного члена союза:

typedef struct 
{ 
    int type; 
    union { 
     char *s; 
     int i; 
    } value; 
} node; 

node n0 = {1, { .s = "string"; }}; 
node n1 = {2, { .i = 123; }}; 

Вам нужно объединение, чтобы иметь имя; в противном случае компилятор будет жаловаться на назначенный инициализатор внутри него.

Синтаксис, который вы пытались использовать node n0 = {type: 1, i: 4}, является недопустимым синтаксисом; похоже, вы пытались использовать назначенные инициализаторы.

+0

Это удивило меня в первый раз, когда я это увидел, но для GCC это действительно юридический (хотя и устаревший) синтаксис инициализатора. – ephemient

+0

, который (я думаю, устарел) синтаксис инициализатора, который я получил от чтения некоторого кода модуля ядра. Структуры «fops» часто записываются таким образом. Теперь я переключусь на C99. Слишком плохо об анонимных профсоюзах, я не знал, что они не стандартные, спасибо, что расчистили это для меня. – Steve