2014-10-29 43 views
-3

我有这样的代码无法设置工会值

union u_value { 
    int i_value; 
    long l_value; 
    float f_value; 
    double d_value; 
    char *cp_value; 
    int type; 
}; 

union u_value create_int_value(int value) { 
    union u_value val; 
    val.i_value = value; 
    val.type = INT; 

    printf("Inside: %d, %d\n", value, val.i_value); 

    return val; 
} 

的问题是,我不能设置内部工会值。

例如:

union u_value val = create_int_value(123); 
printf("%d\n", val.i_value); 

将打印0

我在做什么错?

+1

'type'本身就是工会的成员。设置它将覆盖以前设置的任何值。如果你试图实现一个带标签的联合,你将需要一个'struct',其中一个成员是一个联合,**另一个单独的成员**是类型标签。 – 2014-10-29 11:39:06

+0

@ TheParamagneticCroissant我不知道。谢谢!现在感觉很愚蠢 – ivknv 2014-10-29 11:41:21

+0

好吧,你不必*知道*任何特别的东西。为什么'type'字段是特殊的?它只是工会的另一个成员。它与所有其他成员共享存储空间。你需要**了解**工会是什么...... – 2014-10-29 11:42:08

回答

4

您已将type成员指定为联合的一部分,这当然会导致其内存与其余字段发生冲突。

要创建"tagged union",您必须将标签与联合体分开。喜欢的东西:

struct u_value { 
    int type; 
    union { 
     int i_value; 
     long l_value; 
     float f_value; 
     double d_value; 
     char *cp_value; 
    } value; 
}; 

然后你可以使用:

u_value x; 
x.type = INT; 
x.value.i_value = 4711; 

C11可以使内部union匿名的,这是很方便的。

+0

大多数编译器也会允许漂亮的匿名结构,所以你可以直接访问'x.i_value' :) – Quentin 2014-10-29 11:43:12

1

让我猜,INT被定义为0 ..?您首先将i_value设置为123,然后设置type其中,因为它是工会正在覆盖i_value

你需要做的是从工会

union u_value 
{ 
    int i_value; 
    long l_value; 
    float f_value; 
    double d_value; 
    char *cp_value; 
}; 

struct my_type 
{ 
    union u_value value; 
    int type; 
}; 

struct my_type create_int_value(int value) { 
    struct my_type val; 
    val.value.i_value = value; 
    val.type = INT; 

    printf("Inside: %d, %d\n", value, val.value.i_value); 

    return val; 
} 

拆分类型超出现在的类型不会覆盖值。