2014-07-21 47 views
3

我有很多领域,这将很可能有不同的平台不同的尺寸是C工会填充工会大,因为我可以做到这一点,导致整个工会变得更大。单独的东西不同的是的使用char数组成员

union foo { 
    ... 
    char z[sizeof(union foo)]; 
} 

线将无法编译,当然,因为union foo的规模还没有在这一点众所周知。

有没有让我用char数组填充联合的技巧?

+0

你能请注明您的要求为目的,使一些替代解决方案可以建议? – user1969104

+0

那么,我最初的想法是使用这个联合来实现一个使用这个联合的数组的“通用”列表接口,我想有一种方法来打包二进制数据尽可能有效地使用这样的接口 - 因此字符数组。但是我已经想出了一个更好的方法来做到这一点,它不会浪费任何*类型的空间(更不用说char []了),所以我的要求对于这个问题的目的是没有意义的。这只是一个好奇心。 – Fraxtil

+0

您可以通过将工会地址转换为'unsigned char *'来获取数据 –

回答

1

首先声明一个工会的一切,但阵列,

union foo_almost { 
    int a; 
    wchar_t b; 
    bar *c; 
    baz d; 
}; 

然后声明一切的工会,

union foo { 
    int a; 
    wchar_t b; 
    bar *c; 
    baz d; 
    char z[sizeof(union foo_almost)]; 
}; 

有些人使用宏来做到这一点 - 宣布第一部分为FOO_ALMOST ,但他们真正节省的是打字,

#def FOO_ALMOST \ 
    int a; \ 
    wchar_t b; \ 
    bar *c; \ 
    baz d; 
union foo_almost { 
    FOO_ALMOST 
}; 

then,

union foo { 
    FOO_ALMOST 
    char z[sizeof(union foo_almost)]; 
}; 

现在,sizeof(union foo_almost)和sizeof(union foo)应该是相同的。但是,您的编译器仍可能分配的内存超过union foo类型的对象所占用的内存量。

不需要丑陋的黑客,除非你认为额外的类型联合foo_almost是丑陋的。

通知,

union foo_almost fa; 
union foo f; 
printf("%zu\n", sizeof(fa)); 
printf("%zu\n", sizeof(f)); 
2

那么,有:

union bar { 
    union foo { 
     int a; 
     wchar_t b; 
     bar *c; 
     baz d; 
    } f; 
    char z[sizeof(union foo)]; 
}; 

它得到正确的尺寸,但是你必须访问其他成员当f.坚持。

如果没有f,AFAIK没有办法做到这一点。正如user1969104所示,可能会有更好的解决方案解决您的问题。

下面是一个丑陋的黑客攻击:

#define UNION_FOO_Z(u) (*(unsigned char (*)[sizeof(union foo)])&u) 

用法:

union foo f; 
printf("%zu\n", sizeof UNION_FOO_Z(f)); 

本hack可以具有对准问题(虽然不太可能)。