offsetof()宏 [英] offsetof() macro

查看:76
本文介绍了offsetof()宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




有人可以帮我修一下offsetof()宏吗?


我找到了解释
http://www.embedded.com/shared /print...cleid=18312031

但我担心它对我来说仍然没有意义。


看点似乎是:


((s *)0)取整数零并将其作为指向s的指针。


对于我未训练的眼睛,基本上会导致空指针。

这个表达会导致一些特殊的行为还是我错过了

的东西?


谢谢。


西蒙


-

"成为社交流浪者可以帮助你专注于真正重要的事情

事物,如思考和黑客攻击。 - Eric S. Raymond

Hi,

Can somebody please help me grok the offsetof() macro?

I''ve found an explanation on
http://www.embedded.com/shared/print...cleID=18312031
but I''m afraid it still doesn''t make sense to me.

The sticking point seems to be:

((s *)0) takes the integer zero and casts it as a pointer to s.

To my untrained eye that would basically result in a null pointer. Does
this expression result in some special behaviour or am I missing
something?

Thanks.

Simon

--
"Being a social outcast helps you stay concentrated on the really important
things, like thinking and hacking." - Eric S. Raymond

推荐答案

Simon Morgan写道:
Simon Morgan wrote:



有人可以帮我解决offsetof()宏吗?

我找到了解释
http://www.embedded.com/shared/print...cleID=18312031
但是我担心它对我来说仍然没有意义。

关键点似乎是:

((s *)0)整数零,并将其作为指向s的指针。

对于我未经训练的眼睛,基本上会产生一个空指针。
这个表达式会导致某些特殊行为还是我错过了什么?

Hi,

Can somebody please help me grok the offsetof() macro?

I''ve found an explanation on
http://www.embedded.com/shared/print...cleID=18312031
but I''m afraid it still doesn''t make sense to me.

The sticking point seems to be:

((s *)0) takes the integer zero and casts it as a pointer to s.

To my untrained eye that would basically result in a null pointer. Does
this expression result in some special behaviour or am I missing
something?




s_ptr->项目的偏移量可以视为


((char *)& s_ptr-> item) - ((char *)s_ptr)


而不是必须创建实际的s_ptr要使用这样一个宏,只需使用((s *)常量)即可简化
。通过使

恒定零,它也消除了对上面等式的

的右半部分的需要。


NULL指针没有任何问题,只要你不要
取消引用它。拿它的地址很好。

问题:在NULL不是全部位的平台上会发生什么 -

零?


-

+ ------------------------- + --------- ----------- + ----------------------------- +

| Kenneth J. Brody | www.hvcomputer.com | |

| kenbrody / at\spamcop.net | www.fptech.com | #include< std_disclaimer.h> |

+ ------------------------- + -------------- ------ + ----------------------------- +

不要给我发电子邮件:< mailto:Th ************* @ gmail.com>



The offset of s_ptr->item could be taken as

((char *)&s_ptr->item) - ((char *)s_ptr)

Rather than having to create an actual "s_ptr" to use such a macro, it
can be shortcutted by simply using "((s *)constant)". By making the
"constant" zero, it also eliminates the need for the right-half of the
above equation.

There is nothing wrong with a NULL pointer, as long as you don''t
dereference it. Taking it''s address is fine.
Side question: what happens on platforms where NULL is not all-bits-
zero?

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don''t e-mail me at: <mailto:Th*************@gmail.com>


Simon Morgan< si ** *@16hz.net>写道:
Simon Morgan <si***@16hz.net> wrote:


有人可以帮我修复offsetof()宏吗?


我会试试。

我找到了解释
http://www.embedded.com/shared/print...cleID=18312031
但是我担心它对我来说仍然没有意义。

关键点似乎是:

((s *)0)整数零,并将其作为指向s的指针。

对于我未经训练的眼睛,基本上会产生一个空指针。这个表达式会导致一些特殊的行为吗?或者我错过了什么?
Hi,

Can somebody please help me grok the offsetof() macro?
I''ll try.
I''ve found an explanation on
http://www.embedded.com/shared/print...cleID=18312031
but I''m afraid it still doesn''t make sense to me.

The sticking point seems to be:

((s *)0) takes the integer zero and casts it as a pointer to s.

To my untrained eye that would basically result in a null pointer. Does
this expression result in some special behaviour or am I missing
something?




前言:请注意,offsetof宏的定义是高度的

具体实现。我将在下面使用的只有一个可能的解决方案,它可以在各种系统上运行,而

可能会在其他系统上失败。一个实现甚至可以调用一个

内置函数来计算结构成员的偏移量为black

magic。 (阅读:编译符号表)。


好​​的,让我们看一下:


#define offsetof(s, m)(size_t)&(((s *)0) - > m)


,其中s是结构类型的名称,m是成员的名称$>
在那个结构中。


现在,如果我们想要掌握一个复杂的C表达式,我们只需要在内部读取
out:


0我们取整数常数0,


(s *)0强制转换为指向对象的指针type-s,因此在地址0指向

;我们现在_pretend_在地址0处

类型s的实际对象驻留。


((s *)0) - > m现在看看该对象的成员m,我们这样做

无法访问,而是


&(((s *)0) - > m)take的地址。由于

结构对象的地址为0,因此m的地址恰好等于其以字节为单位的偏移量。


(size_t)&(((s *)0) - > m)最后,我们将结果转换为合适的

积分数据类型。


但是,请注意,此特定实现依赖于以下事实:

基础架构允许_meaningfully_转换

的整数值到内存地址,反之亦然。


HTH

祝你好运

-

Irrwahn Grausewitz(ir ***** **@freenet.de)

欢迎来到clc: http://www.ungerhu.com/jxh/clc.welcome.txt

clc faq-list: http://www.faqs.org/faqs/C-faq/faq/

clc经常回答: http://benpfaff.org/writings/clc



Preamble: note that the definition of the offsetof macro is highly
implementation specific. The one I''ll use below is only one possible
solution, which happens to work on a variety of systems, while
miserably failing on others. An implementation may even call an
inbuilt function to calculate the offset of struct members by "black
magic" (read: compiler symbol table).

Ok, let''s have a look at it:

#define offsetof(s,m) (size_t)&(((s *)0)->m)

with s being the name of a structure type and m the name of a member
within that structure.

Now, if we want to get a grip at a complex C expression, we simply
read it inside out:

0 We take the integer constant 0,

(s *)0 cast to a pointer-to-object-of-type-s, thus pointing
at address 0; we now _pretend_ that at address 0 an
actual object of type s resides.

((s *)0)->m Now look at the member m of that object, which we do
not access, but instead

&(((s *)0)->m) take the address of. Since the address of the
structure object is 0, the address of m happens to
equal its offset in bytes.

(size_t)&(((s *)0)->m) Finally, we cast the result to a suitable
integral data type.

Note, however, that this specific implementation relies upon the fact,
that the underlying architecture allows for _meaningfully_ conversion
of an integral value into a memory address an vice versa.

HTH
Best regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc frequent answers: http://benpfaff.org/writings/clc.


Kenneth Brody写道:
Kenneth Brody wrote:
Simon Morgan写道:
Simon Morgan wrote:

你好,

有人可以帮我修一下offsetof()宏吗?

>我已经找到了解释
http ://www.embedded.com/shared/print...cleID=18312031
但我担心它对我来说仍然没有意义。
关键点似乎是:

((s *)0)取整数零并将其作为指向s的指针。

对于我未经训练的眼睛基本上会产生一个空指针。
这个表达式会导致某些特殊行为还是我错过了什么?

Hi,

Can somebody please help me grok the offsetof() macro?

I''ve found an explanation on
http://www.embedded.com/shared/print...cleID=18312031
but I''m afraid it still doesn''t make sense to me.

The sticking point seems to be:

((s *)0) takes the integer zero and casts it as a pointer to s.

To my untrained eye that would basically result in a null pointer. Does
this expression result in some special behaviour or am I missing
something?



s_ptr->项目的偏移量可以视为

((char *)& s_ptr-> item) - ((char *)s_ptr)

而不是必须创建一个实际的s_ptr使用这样的宏,只需使用((s *)常量)就可以缩短它的速度。通过使
恒定零,它也消除了对上面等式的右半部分的需要。

NULL指针没有任何问题,只要你没有
取消引用它。拿它的地址很好。

附带问题:在NULL不是全部位的平台上会发生什么 -
零?



The offset of s_ptr->item could be taken as

((char *)&s_ptr->item) - ((char *)s_ptr)

Rather than having to create an actual "s_ptr" to use such a macro, it
can be shortcutted by simply using "((s *)constant)". By making the
"constant" zero, it also eliminates the need for the right-half of the
above equation.

There is nothing wrong with a NULL pointer, as long as you don''t
dereference it. Taking it''s address is fine.
Side question: what happens on platforms where NULL is not all-bits-
zero?




两者都是NULL和offsetof在< stddef.h>中定义(7.17常见定义

< stddef.h>)。


NULL是实现定义的,但是(6.3.2.3指针)是一个整数常量
值为0的
与NULL相同。


我想如果,例如。实现决定NULL的值是
0x1234,然后常数0,当用作指针时,将等于0x1234。


如果NULL是定义为0以外的其他东西(包括非整数值),

这样的构造如下:

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

不会产生正确的值,因此为什么它在< stddef.h>

和NULL中定义。


请注意,我不是C标准方面的专家,不像这里的很多人,而且我b $ b可能会提供完全错误的信息。 />

BTW,我不得不检索offsetof一个数组元素,所以这里是一个

补充宏,只有NULL值为0才有效,如果我说的话

以上是正确的。


#define array_offsetof(BASETYPE,ARRAY,INDEX)((size_t)&((BASETYPE(*)ARRAY

0)[0] INDEX)


ex。:

int a [5] [10] [15];

/ *偏移[1] [3] * /

int offset = array_offsetof(int,[5] [10] [15],[1] [3]);

-

Eric Laberge



Both "NULL" and "offsetof" are defined in <stddef.h> (7.17 Common de?nitions
<stddef.h>).

NULL is implementation-defined, but (6.3.2.3 Pointers) an integer constant
with value 0 is the same as NULL.

I suppose if, eg. the implementation decided that the value of NULL is
0x1234, then constant 0, when used as a pointer, would be equal to 0x1234.

If NULL is defined as something other than 0 (incl. non-integer values),
such a construct as:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
would not yield the correct value, hence why it is defined in <stddef.h>
along with NULL.

Note that I''m not an expert on the C standard unlike many people here, and I
could be giving totally wrong information.

BTW, I had to retrieve the "offsetof" of an array element, so here''s a
complementary macro, only valid with a NULL value of 0, if what I said
above is correct.

#define array_offsetof(BASETYPE,ARRAY,INDEX) ((size_t) &((BASETYPE(*)ARRAY
0)[0]INDEX)

ex.:
int a[5][10][15];
/* offset of a[1][3] */
int offset = array_offsetof(int, [5][10][15], [1][3]);
--
Eric Laberge


这篇关于offsetof()宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆