简体   繁体   English

通过基地址+ XX的偏移量和struct_name-> XX访问结构成员XX的区别

[英]Different between accessing a struct member XX by base address + offset of XX and struct_name->XX

I am using an open source library(Easy C State Machine). 我正在使用一个开源库(Easy C状态机)。 When I review the code, I found the struct is accessed by base address + offset of X, something like follows. 当我查看代码时,发现结构是通过基地址+ 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);

instead of: 代替:

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

What's the difference between the above two? 两者之间有什么区别? Any advantage of the former one? 前者有什么优势吗?

The library is written in ANSI C. But it is said that it can only support two architecture: x86 and amd64. 该库是用ANSI C编写的。但是据说它仅支持两种体系结构:x86和amd64。 Since I want to use it on another arch, I reviewed the source code and find the only architecture-related code is the OFF_SET_OF_XXs. 由于我想在另一个拱门上使用它,因此我查看了源代码,发现唯一与体系结构相关的代码是OFF_SET_OF_XXs。

First of all, I'd like to point out the left-most cast to type X is not necessary so you could simplify it to: 首先,我想指出的是,不必将最左侧的类型强制转换为X因此可以将其简化为:

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

Still, I don't see the purpose of using a macro like this. 不过,我看不出使用这样的宏的目的。 It throws away type safety and the syntax is cumbersome. 它丢弃了类型安全性,并且语法繁琐。

The code that the compiler generates for the two different ways should be pretty similar, if not identical. 编译器为两种不同方式生成的代码即使不是完全相同,也应该非常相似。 But what compiler and platform is this library supposed to be compiled on? 但是该库应该在什么编译器和平台上进行编译? If there happened to be a performance gain from using GET_MEMBER in that compiler then that could be why they are using it. 如果在该编译器中使用GET_MEMBER带来了性能GET_MEMBER ,那么这可能就是他们使用它的原因。

EDIT 1: My guess is that the original author of the library did not know about structs and invented his own thing similar to structs using alloc, pointers, and macros. 编辑1:我的猜测是该库的原始作者不了解结构,并使用alloc,指针和宏发明了自己的类似于结构的东西。 Now that he has made the library open source, others are trying to convert it to use structs but there is a lot of code to convert and they haven't finished yet. 现在,他已将库开放为开源库,其他人正在尝试将其转换为使用结构,但是有许多代码需要转换,但尚未完成。

The closest thing I have seen with a legitimate purpose (borderline, IMO) is the Linux kernel's container_of macro. 我看到的出于合法目的(边界线,IMO)最接近的东西是Linux内核的container_of宏。

But for the example you give, there is absolutely no reason to do this other than "the author is a moron". 但是对于您给出的示例,除了“作者是白痴”以外,没有其他理由这样做。 It gains nothing in performance, sacrifices readability, and invites annoying bugs (eg, what happens if somebody decides to change i to a long someday?) 它获得什么性能,牺牲可读性,并邀请恼人的错误(例如,会发生什么,如果有人决定改变ilong哪天?)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM