通过基址+ XX的偏移量和struct_name-> XX访问结构成员XX之间有所不同

时间:2011-06-22 14:52:16

标签: c

我使用的是开源库(Easy C State Machine)。当我查看代码时,我发现结构是通过基地址+偏移X来访问的,如下所示。

#define OFF_SET_OF_XX 1
#define GET_MEMBER(X, Y, Z) ((X)(*((X*)(((int*)(Y))+Z))))

typedef struct Foo {
int i;
int XX;
}Foo;

Foo *foo1 = alloc(...);
int j = GET_MEMBER(int, foo1, OFF_SET_OF_XX);

而不是:

Foo *foo1 = alloc(...);
int j = foo1->XX;

以上两者有什么区别?前者的任何优势?

该库是用ANSI C编写的。但据说它只能支持两种架构: x86和amd64。由于我想在另一个arch上使用它,我查看了源代码,发现唯一与架构相关的代码是OFF_SET_OF_XXs。

2 个答案:

答案 0 :(得分:2)

首先,我想指出最左侧的演员类型X不是必需的,所以你可以将其简化为:

#define GET_MEMBER(X, Y, Z) (*((X*)(((int*)(Y))+Z)))

但是,我没有看到像这样使用宏的目的。它抛弃了类型安全性,语法很麻烦。

编译器为两种不同方式生成的代码应该非常相似,如果不相同的话。但是这个库应该编译的编译器和平台是什么?如果在该编译器中使用GET_MEMBER恰好获得了性能提升,那么这就是他们使用它的原因。

编辑1:我的猜测是该库的原作者不了解结构并发明了类似于使用alloc,pointers和mac的结构的自己的东西。现在他已经将库变为开源,其他人正在尝试将其转换为使用结构,但是有很多代码需要转换,而且还没有完成。

答案 1 :(得分:1)

我看到的最合适的用途(边界线,IMO)是Linux内核的container_of宏。

但是对于你给出的例子,除了“作者是白痴”之外,绝对没有理由这样做。它在性能上没有任何好处,牺牲了可读性,并且引发了烦人的错误(例如,如果有人决定有一天将i更改为long会发生什么?)