找出结构中成员偏移量的不同方法 [英] different way of finding out offsetof a member in structure

查看:55
本文介绍了找出结构中成员偏移量的不同方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我有一个疑问。测试程序如下。它使用两种方式来确定变量在结构中的偏移量。我执行了

程序并找到了相同的结果。


我的问题是什么区别


1 )(无符号长)&((struct foobar *)0) - > foo



2)(无符号长)((char *)& tmp .boo - (char *)& tmp)


为什么第二个选项不用于offsetof宏。


什么是明显的第一种语法的优点?

第二种语法有什么问题吗?


谢谢

Abhimanyu


= ================================

#include< stdio。 h>

#include< stdlib.h>


struct foobar {

unsigned int foo;

char bar;

char boo;

};


int main()

{

struct foobar tmp;


printf("& tmp的地址=%p\\\
\ n",& tmp );

printf(地址tmp-> foo =%p \t偏移量tmp-> foo =%lu \ n,

& tmp.foo,(unsigned long)&((struct foobar *)0) - > foo);

printf(" tmp-> bar =%p \的地址吨偏移tmp-> bar =%lu \ n",

& tmp.bar,(unsigned long)&((struct foobar *)0) - > bar);

printf("地址tmp-> boo =%p \t偏移量tmp-> boo =%lu \ n \ nn",

& tmp.boo,(unsig ned long)&((struct foobar *)0) - > boo);


printf(" tmp-> foo =%p \t offset of address of tmp-> foo =%lu \ n",

& tmp.foo,(unsigned long)((char *)& tmp.foo - (char *)& tmp) );

printf(" tmp-> bar =%p \t偏移量tmp-> bar =%lu \ n",

& tmp.bar,(unsigned long)((char *)& tmp.bar - (char *)& tmp));

printf(" tmp-> boo的地址=%p \t偏移量tmp-> boo =%lu \ n \ n",

& tmp.boo,(unsigned long)((char *)& tmp .boo - (char *)& tmp));


printf(Hello world!\ n);

返回0; < br $>
}

结果

==================

地址& tmp = 0022FF70


地址tmp-> foo = 0022FF70偏移量tmp-> foo = 0

地址tmp - > bar = 0022FF74 tmp的偏移量 - > bar = 4

tmp的地址 - > boo = 0022FF75 offset o f tmp-> boo = 5

tmp的地址 - > foo = 0022FF70 tmp的偏移量 - > foo = 0

tmp的地址> bar = 0022FF74 tmp的偏移量 - > bar = 4

tmp的地址 - > boo = 0022FF75 tmp的偏移量 - > boo = 5


Hello world!


按ENTER继续。

解决方案

11月5日,12:56 pm,abhimany ... @ gmail.com < abhimany ... @ gmail.com>

写道:


嗨大家好,


我有一个疑问。测试程序如下。它使用两种方式来确定变量在结构中的偏移量。我执行了

程序并找到了相同的结果。


我的问题是什么区别


1 )(无符号长)&((struct foobar *)0) - > foo



2)(无符号长)((char *)& tmp .boo - (char *)& tmp)


为什么第二个选项不用于offsetof宏。


什么是明显的第一种语法的优点?

第二种语法有什么问题吗?


谢谢

Abhimanyu


= ================================

#include< stdio。 h>

#include< stdlib.h>


struct foobar {

unsigned int foo;

char bar;

char boo;


};


int main()

{

struct foobar tmp;


printf("& tmp的地址=%p\\\
\ n" ,& tmp);

printf("地址tmp-> foo =%p \t偏移量tmp-> foo =%lu \ n",

& tmp.foo,(unsigned long)&((struct foobar *)0) - > foo);

printf(" tmp-> bar的地址= %p \t偏移量tmp-> bar =%lu \ n",

& tmp.bar,(unsigned long)&((struct foobar *)0) - > ; bar);

printf("地址tmp-> boo =%p \t偏移量tmp-> b oo =%lu \ n \ n",

& tmp.boo,(unsigned long)&((struct foobar *)0) - > boo);


printf("地址tmp-> foo =%p \t偏移量tmp-> foo =%lu \ n",

& tmp.foo,(unsigned long)((char *)& tmp.foo - (char *)& tmp));

printf(" tmp-> bar =% p \t offset of tmp-> bar =%lu \ n",

& tmp.bar,(unsigned long)((char *)& tmp.bar - (char *)& tmp));

printf(" tmp-> boo =%p \t偏移量tmp-> boo =%lu \ n \ nn" ,

& tmp.boo,(unsigned long)((char *)& tmp.boo - (char *)& tmp));


printf(Hello world!\ n);

返回0;


}


结果

==================

& tmp的地址= 0022FF70


地址tmp-> foo = 0022FF70偏移量tmp-> foo = 0

地址of tmp-> bar = 0022FF74 tmp-> bar = 4

tmp的地址 - > boo = 0022FF75 tmp的偏移量 - > boo = 5

地址tmp->; foo = 0022FF70偏移量tmp-> foo = 0

地址tmp-> bar = 0022FF74偏移量tmp-> bar = 4

地址tmp-> boo = 0022FF75 tmp的偏移量 - > boo = 5

Hello world!


按ENTER继续。



好​​问题。


但是,我认为(unsigned long)&((struct foobar *)0) - > bar是

内部实现为

(无符号长)((char *)& tmp.boo - (char *)& tmp)。


我想,两者都意味着相同(我不确定)。 !!


Karthik Balaguru



11月5日下午1:17,karthikbalaguru< ; karthikbalagur ... @ gmail.com>

写道:


11月5日下午12:56,abhimany .. 。@ gmail.com" < abhimany ... @ gmail.com>

写道:


嗨大家好,


我有一个疑问。测试程序如下。它使用两种方式来确定变量在结构中的偏移量。我执行了

程序并找到了相同的结果。


我的问题是
之间有什么区别


1)( unsigned long)&((struct foobar *)0) - > foo



2)(unsigned long)((char *)& tmp.boo - (char *)& tmp)


为什么第二个选项不用于offsetof宏。


第一种语法的明显优势是什么?

秒语法有什么问题吗?


谢谢

Abhimanyu


=================================


#include< stdio.h>

#include< stdlib.h>


struct foobar {

unsigned int foo;

char bar;

char boo;


};


int main()

{

struct foobar tmp;


printf("& tmp的地址=%p \ n \ n",& tmp);

printf("地址tmp-> foo =%p \t偏移量tmp-> foo =%lu \ n",

& tmp.foo, (unsigned long)&((struct foobar *)0) - > foo);

printf(" tmp-> bar的地址= tmp的%p \ t偏移量 - > ; bar =%lu \ n",

& tmp.bar,(unsigned long)&((struct foobar *)0) - > bar);

printf("地址tmp-> boo =%p \t偏移量tmp-> boo =%lu \ n \ n",

& tmp.boo ,(unsigned long)&((struct foobar *)0) - > boo);


printf(" tmp-> foo =%p \t偏移量tmp-> foo =%lu \ n" ;,

& tmp.foo,(unsigned long)((char *)& tmp.foo - (char *)& tmp));

printf (地址tmp-> bar =%p \t偏移量tmp-> bar =%lu \ n,

& tmp.bar,(unsigned long)( (char *)& tmp.bar - (char *)& tmp));

printf("地址tmp-> boo =%p \t偏移量tmp-> ; boo =%lu \ n \ n",

& tmp.boo,(unsigned long)((char *)& tmp.boo - (char *)& tmp) );


printf(" Hello world!\ n");

返回0;


}


结果

==================

& tmp的地址= 0022FF70


地址tmp->; foo = 0022FF70偏移量tmp-> foo = 0

地址tmp-> bar = 0022FF74偏移量tmp-> bar = 4

地址tmp-> boo = 0022FF75偏移量tmp-> boo = 5


地址tmp-> foo = 0022FF70 tmp的偏移量 - > foo = 0

tmp的地址 - > bar = 0022FF74 tmp的偏移量 - > bar = 4

tmp的地址> boo = 0022FF75 tmp的偏移量 - > boo = 5


Hello world!


按ENTER继续。



好​​问题。


但是,我认为(无符号长)&((struct foobar *)0) - > bar是

内部实现为

(无符号长)((char *)& tmp.boo - (char *)& tmp)。


我想,两者都意味着相同(我不确定)。 !!


Karthik Balaguru



否(无符号长)&((struct foobar *)0) - > ; bar与

(unsigned long)((char *)& tmp.boo - (char *)& tmp)不同。


(unsigned long)&((struct foobar *)0) - > bar基本上是做

跟随的事情:


1)Typecast the带结构的ZEROth内存。

2)现在假设ZEROth位置确实为0,那么指向

成员变量将给出变量的内存位置。 />

现在,如果ZerOth位置在内部不存在0怎么办?然后这个

构造将失败!


问候,

Abhimanyu


" AB ********* @ gmail.com" < ab ********* @ gmail.comwrites:


我有一个疑问。测试程序如下。它使用两种方式来确定变量在结构中的偏移量。我执行了

程序并找到了相同的结果。


我的问题是什么区别


1 )(无符号长)&((struct foobar *)0) - > foo



2)(无符号长)((char *)& tmp .boo - (char *)& tmp)


为什么第二个选项不用于offsetof宏。


什么是明显的第一种语法的优点?

秒语法有什么问题吗?



[...]


第一个表单调用未定义的行为。请注意,这并不意味着它不会起作用,或者它会爆炸;行为只是

并不是由标准定义的。实现可以使用类似于你的第一个例子的东西来实现offsetof,利用特定编译器行为的
。 (你不能可靠地在便携式代码中执行

,这就是为什么offsetof是

实现的一部分。)


第二种形式并没有调用未定义的行为,尽管我可以说b $ b告诉,但它不能用于实现offsetof;第一个参数

到offsetof是结构类型,而不是结构对象。


-

Keith Thompson(The_Other_Keith) ks***@mib.org < http://www.ghoti.net/~kst>

寻找圣地亚哥地区的软件开发工作。

我们必须做点什么。这是事情。因此,我们必须这样做。

- Antony Jay和Jonathan Lynn,是部长


Hi Guys,

I have one doubt. The test program is given below. It uses two way of
finding out the offset of a variable in structure. I executed the
program and found the same result.

My question is what is difference between

1) (unsigned long) &((struct foobar *)0)->foo
and
2) (unsigned long)((char*)&tmp.boo - (char*)&tmp)

And why the second option is not used for offsetof macro.

What is obvious advantage of the first syntax? Anything wrong with the
second syntax?

Thanks
Abhimanyu

=================================

#include <stdio.h>
#include <stdlib.h>

struct foobar{
unsigned int foo;
char bar;
char boo;
};

int main()
{
struct foobar tmp;

printf("address of &tmp is= %p\n\n", &tmp);
printf("address of tmp->foo= %p \t offset of tmp->foo= %lu\n",
&tmp.foo, (unsigned long) &((struct foobar *)0)->foo);
printf("address of tmp->bar= %p \t offset of tmp->bar= %lu\n",
&tmp.bar, (unsigned long) &((struct foobar *)0)->bar);
printf("address of tmp->boo= %p \t offset of tmp->boo= %lu\n\n",
&tmp.boo, (unsigned long) &((struct foobar *)0)->boo);

printf("address of tmp->foo= %p \t offset of tmp->foo= %lu\n",
&tmp.foo, (unsigned long)((char*)&tmp.foo - (char*)&tmp) );
printf("address of tmp->bar= %p \t offset of tmp->bar= %lu\n",
&tmp.bar, (unsigned long)((char*)&tmp.bar - (char*)&tmp) );
printf("address of tmp->boo= %p \t offset of tmp->boo= %lu\n\n",
&tmp.boo, (unsigned long)((char*)&tmp.boo - (char*)&tmp) );

printf("Hello world!\n");
return 0;
}
Result
==================
address of &tmp is= 0022FF70

address of tmp->foo= 0022FF70 offset of tmp->foo= 0
address of tmp->bar= 0022FF74 offset of tmp->bar= 4
address of tmp->boo= 0022FF75 offset of tmp->boo= 5

address of tmp->foo= 0022FF70 offset of tmp->foo= 0
address of tmp->bar= 0022FF74 offset of tmp->bar= 4
address of tmp->boo= 0022FF75 offset of tmp->boo= 5

Hello world!

Press ENTER to continue.

解决方案

On Nov 5, 12:56 pm, "abhimany...@gmail.com" <abhimany...@gmail.com>
wrote:

Hi Guys,

I have one doubt. The test program is given below. It uses two way of
finding out the offset of a variable in structure. I executed the
program and found the same result.

My question is what is difference between

1) (unsigned long) &((struct foobar *)0)->foo
and
2) (unsigned long)((char*)&tmp.boo - (char*)&tmp)

And why the second option is not used for offsetof macro.

What is obvious advantage of the first syntax? Anything wrong with the
second syntax?

Thanks
Abhimanyu

=================================

#include <stdio.h>
#include <stdlib.h>

struct foobar{
unsigned int foo;
char bar;
char boo;

};

int main()
{
struct foobar tmp;

printf("address of &tmp is= %p\n\n", &tmp);
printf("address of tmp->foo= %p \t offset of tmp->foo= %lu\n",
&tmp.foo, (unsigned long) &((struct foobar *)0)->foo);
printf("address of tmp->bar= %p \t offset of tmp->bar= %lu\n",
&tmp.bar, (unsigned long) &((struct foobar *)0)->bar);
printf("address of tmp->boo= %p \t offset of tmp->boo= %lu\n\n",
&tmp.boo, (unsigned long) &((struct foobar *)0)->boo);

printf("address of tmp->foo= %p \t offset of tmp->foo= %lu\n",
&tmp.foo, (unsigned long)((char*)&tmp.foo - (char*)&tmp) );
printf("address of tmp->bar= %p \t offset of tmp->bar= %lu\n",
&tmp.bar, (unsigned long)((char*)&tmp.bar - (char*)&tmp) );
printf("address of tmp->boo= %p \t offset of tmp->boo= %lu\n\n",
&tmp.boo, (unsigned long)((char*)&tmp.boo - (char*)&tmp) );

printf("Hello world!\n");
return 0;

}

Result
==================
address of &tmp is= 0022FF70

address of tmp->foo= 0022FF70 offset of tmp->foo= 0
address of tmp->bar= 0022FF74 offset of tmp->bar= 4
address of tmp->boo= 0022FF75 offset of tmp->boo= 5

address of tmp->foo= 0022FF70 offset of tmp->foo= 0
address of tmp->bar= 0022FF74 offset of tmp->bar= 4
address of tmp->boo= 0022FF75 offset of tmp->boo= 5

Hello world!

Press ENTER to continue.

Good Question.

But, i think that (unsigned long) &((struct foobar *)0)->bar is
internally implemented as
(unsigned long)((char*)&tmp.boo - (char*)&tmp).

I think, both mean the same(I am not sure). !!

Karthik Balaguru



On Nov 5, 1:17 pm, karthikbalaguru <karthikbalagur...@gmail.com>
wrote:

On Nov 5, 12:56 pm, "abhimany...@gmail.com" <abhimany...@gmail.com>
wrote:

Hi Guys,

I have one doubt. The test program is given below. It uses two way of
finding out the offset of a variable in structure. I executed the
program and found the same result.

My question is what is difference between

1) (unsigned long) &((struct foobar *)0)->foo
and
2) (unsigned long)((char*)&tmp.boo - (char*)&tmp)

And why the second option is not used for offsetof macro.

What is obvious advantage of the first syntax? Anything wrong with the
second syntax?

Thanks
Abhimanyu

=================================

#include <stdio.h>
#include <stdlib.h>

struct foobar{
unsigned int foo;
char bar;
char boo;

};

int main()
{
struct foobar tmp;

printf("address of &tmp is= %p\n\n", &tmp);
printf("address of tmp->foo= %p \t offset of tmp->foo= %lu\n",
&tmp.foo, (unsigned long) &((struct foobar *)0)->foo);
printf("address of tmp->bar= %p \t offset of tmp->bar= %lu\n",
&tmp.bar, (unsigned long) &((struct foobar *)0)->bar);
printf("address of tmp->boo= %p \t offset of tmp->boo= %lu\n\n",
&tmp.boo, (unsigned long) &((struct foobar *)0)->boo);

printf("address of tmp->foo= %p \t offset of tmp->foo= %lu\n",
&tmp.foo, (unsigned long)((char*)&tmp.foo - (char*)&tmp) );
printf("address of tmp->bar= %p \t offset of tmp->bar= %lu\n",
&tmp.bar, (unsigned long)((char*)&tmp.bar - (char*)&tmp) );
printf("address of tmp->boo= %p \t offset of tmp->boo= %lu\n\n",
&tmp.boo, (unsigned long)((char*)&tmp.boo - (char*)&tmp) );

printf("Hello world!\n");
return 0;

}

Result
==================
address of &tmp is= 0022FF70

address of tmp->foo= 0022FF70 offset of tmp->foo= 0
address of tmp->bar= 0022FF74 offset of tmp->bar= 4
address of tmp->boo= 0022FF75 offset of tmp->boo= 5

address of tmp->foo= 0022FF70 offset of tmp->foo= 0
address of tmp->bar= 0022FF74 offset of tmp->bar= 4
address of tmp->boo= 0022FF75 offset of tmp->boo= 5

Hello world!

Press ENTER to continue.


Good Question.

But, i think that (unsigned long) &((struct foobar *)0)->bar is
internally implemented as
(unsigned long)((char*)&tmp.boo - (char*)&tmp).

I think, both mean the same(I am not sure). !!

Karthik Balaguru

No the (unsigned long) &((struct foobar *)0)->bar is not same as
(unsigned long)((char*)&tmp.boo - (char*)&tmp).

The (unsigned long) &((struct foobar *)0)->bar is basically doing the
following thing:

1) Typecast the ZEROth memory with the structure.
2) Now assuming that ZEROth location is indeed 0, then pointing to the
member variable will give the memory location of the variable.

Now what if ZEROth location is not present at 0 internally? Then this
construct will fail!

Regards,
Abhimanyu


"ab*********@gmail.com" <ab*********@gmail.comwrites:

I have one doubt. The test program is given below. It uses two way of
finding out the offset of a variable in structure. I executed the
program and found the same result.

My question is what is difference between

1) (unsigned long) &((struct foobar *)0)->foo
and
2) (unsigned long)((char*)&tmp.boo - (char*)&tmp)

And why the second option is not used for offsetof macro.

What is obvious advantage of the first syntax? Anything wrong with the
second syntax?

[...]

The first form invokes undefined behavior. Note that this doesn''t
mean that it doesn''t work, or that it blows up; the behavior just
isn''t defined by the standard. Implementations can use something
similar to your first example to implement offsetof, taking advantage
of the behavior of the particular compiler. (You can''t reliably do
that in portable code, which is why offsetof is part of the
implementation.)

The second form doesn''t invoke undefined behavior as far as I can
tell, but it can''t be used to implement offsetof; the first argument
to offsetof is a struct type, not a struct object.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


这篇关于找出结构中成员偏移量的不同方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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