struct,对齐和宏的难题

时间:2008-07-24 16:54:23   来源:论坛整理  作者:  编辑:chinaitzhe
希望实现这样一个宏:

STRUCT_PADDING_TO(x)

其含义是:让struct对齐到x字节

比如

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



struct s1 {

    STRUCT_PADDING_TO(32);

    char a;

    STRUCT_PADDING_TO(48);

    char b;

};



那么这个struct被展开后应该是类似这样的形式

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



struct s1 {

    char __padding1[32];

    char a;  /* 被对齐到第32个字节 */

    char __padding2[15];

    char b;  /* 被对齐到第48个字节 */

};



各位高手有什么思路么?

我觉得首先要知道,成员相对结构的地址,如:

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



struct s1 a;

(void *)(&a) - (void *)(&a.a);



如何在编译期得到呢?又或者有什么其他的方法?

还有如何使宏自动编号呢?使用全局变量?
网友回复:编译期么?
这个轻易。
网友回复:offsetof
网友回复:编译期的方法 貌似没有想出来

akirya有什么好方法?
网友回复:可以用union实现 不必用宏
网友回复:没合楼主的意
不过我觉得因为取偏移时接口题定义还不完全,没法使用其类型,在这儿卡壳了

引用 2 楼 akirya 的回复:
offsetof

网友回复:这个思路可以试试,不错

引用 4 楼 pustian 的回复:
可以用union实现 不必用宏

网友回复:查了一下MinGW中offsetof的实现

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)


网友回复:
引用 4 楼 pustian 的回复:
可以用union实现 不必用宏


一点头绪还没有呢……等我想想。
网友回复:刚刚看明白你的啥意思

定义的时候还不知道成员的位置,而你的宏有得需要这个没定义出来的结构体的成员位置。有点矛盾。
网友回复:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



struct s1 {

    int a;

    char b[offsetof(struct s1, a)];

};



这么引用是非法的,编译器报struct s1是个imcomplete类型
网友回复:来学习的o(∩_∩)o...
网友回复:up

网友回复: 该回复于2008-07-09 18:02:07被版主删除
网友回复:也就是说定义一个宏的时候,必须知道这个宏之前所定义的全部成员的sizeof之合

或者简单点说,应该是前一个成员的offset加上它的sizeof。

用union似乎也有点意思
变成这样:

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



union s1 {

    struct {

        PADDING_TO(32);

        char a;

    } a;

    struct {

        PADDING_TO(48);

        char b;

    } b;

};



这时候PADDING_TO(x)倒是变得简单了,

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



#define PADDING_TO(x)   char __padding[x];



可是引用起来麻烦:

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



struct s1 exp;

exp.a.a = 'a';

exp.b.b = 'b';



定义起来也麻烦,并且通用性差
网友回复:试验了一下,神奇地发现这样可以:

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



#include <stdio.h>



#define PADDING_TO(x, type)   \

    struct {  \

        char __padding[x];  \

        type;  \

    } ;\



union s1 {

    PADDING_TO(32, char a);

    PADDING_TO(48, char b);

};



int main()

{

    union s1 a;

    a.a = 'A';

    a.b = 'B';



    printf("sizeof (a) == %d\n", sizeof (a));



    return 0;

}



输出结果49,符合我的预期
网友回复:我发现上面这个解法不能完全符合我的要求,因为下面这个操作由于union的关系与我预期的不符:

union s1 {
PADDING_TO(32, char a);
PADDING_TO(48, char b);
char c;
char d;
};

sizeof的结果是49,因为c,d和两个PADDING_TO使用了同样的一块内存
关键字:struct,齐宏,难题,

相关文章

文章评论

共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面