By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,837 Members | 1,358 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,837 IT Pros & Developers. It's quick & easy.

Why there is no memory access violation?

P: n/a
Have following code snip:

struct struc {
int member1;
int member2;
} ;
printf("&((struc*)0)->member2=%p\n", &((struc*)0)->member2);

In VC7.1, the output is 4, the offset of member2 in struc.

I wonder why there is no memory access violation for
"((struc*)0)->member2" ?
And why the output is the offset of struc?

what's the output in pure C compiler? I have no C compiler at hand now.

Nov 22 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
aling wrote:
Have following code snip:

struct struc {
int member1;
int member2;
} ;
printf("&((struc*)0)->member2=%p\n", &((struc*)0)->member2);

In VC7.1, the output is 4, the offset of member2 in struc.
That's a sensible behavior.
I wonder why there is no memory access violation for
That would be another sensible behavior.
"((struc*)0)->member2" ?
And why the output is the offset of struc?

what's the output in pure C compiler? I have no C compiler at hand now.


The code is illegal and it is undefined behavior. That means the system
could do anything. Don't dereference a null pointer. On my system,
running this program automatically closes my web browser and opens my
word processor. Since I have very limited amount of RAM, this took
approximately 2 hours.

Jonathan

Nov 22 '05 #2

P: n/a
Jonathan Mcdougall wrote:
aling wrote:
Have following code snip:

struct struc {
int member1;
int member2;
} ;
printf("&((struc*)0)->member2=%p\n", &((struc*)0)->member2);

In VC7.1, the output is 4, the offset of member2 in struc.

That's a sensible behavior.

I wonder why there is no memory access violation for

That would be another sensible behavior.

"((struc*)0)->member2" ?
And why the output is the offset of struc?

what's the output in pure C compiler? I have no C compiler at hand now.

The code is illegal and it is undefined behavior. That means the system
could do anything. Don't dereference a null pointer. On my system,
running this program automatically closes my web browser and opens my
word processor.


Me too! Except on mine it also composes and posts this reply. In fact,
I'm not even aware that I just posted this.
Nov 22 '05 #3

P: n/a
aling wrote:
Have following code snip:

struct struc {
int member1;
int member2;
} ;
printf("&((struc*)0)->member2=%p\n", &((struc*)0)->member2);

In VC7.1, the output is 4, the offset of member2 in struc.

I wonder why there is no memory access violation for
"((struc*)0)->member2" ?
And why the output is the offset of struc?


There is no memory access violation because there is no memory access.
You have simply asked the compiler to compute the address of the member,
not to read the member. The expression is composed entirely of
constants and the result is computed at compile time.

The output is address 4 because that is the offset from the address of 0
that you supplied.

--
Scott McPhillips [VC++ MVP]

Nov 22 '05 #4

P: n/a
Why the result of &((struc*)0)->member2 is a offset instead of address?

Why the two results of following code is different, and one is memory
address, the other is offset?

struct struc {
int member1;
int member2;
} astruc, * p_struc=&astruc, *p_null=0;
printf("&p_struc->member2=%p\n", &p_struc->member2); // this result is
a memory address
printf("&p_null->member2=%p\n", &p_null->member2); // this result is
offset of member2

Nov 22 '05 #5

P: n/a
Now I understand. The result of &((struc*)0)->member2 is not offset, it
is a memory address, though it can be used as one offset.

Nov 22 '05 #6

P: n/a
aling wrote:
Now I understand. The result of &((struc*)0)->member2 is not offset, it
is a memory address, though it can be used as one offset.


The code is not legal, despite the fact that it works. If you need to do
this sort of thing you should use the offsetof macro defined in
<stdlib.h>. Most likely the offsetof macro will do exactly what you are
doing above, but the offsetof macro is guaranteed to work (on C style
structs).

john
Nov 22 '05 #7

P: n/a
> defined in
<stdlib.h>.


I meant <stddef.h>

john
Nov 22 '05 #8

P: n/a
aling wrote:
Why the result of &((struc*)0)->member2 is a offset instead of address?

Why the two results of following code is different, and one is memory
address, the other is offset?

struct struc {
int member1;
int member2;
} astruc, * p_struc=&astruc, *p_null=0;
printf("&p_struc->member2=%p\n", &p_struc->member2); // this result is
a memory address
printf("&p_null->member2=%p\n", &p_null->member2); // this result is
offset of member2


The program is calculating the address of the member as if the object
itself were located at memory address 0. So addresses are identical to
offsets since they are both being measured from the same reference
point. Note that the memory address 0 as used in this program is not
necessarily the address that the NULL pointer references. And it is
even conceivable that memory address 0 could be a valid memory location
on a system somewhere. For that reason, the null pointer "0" is, in
C++, a symbolic representation of an invalid object address. The actual
null pointer address used when the code is compiled can be different
and would depend on the implementation.

And as alarming as this program appears, it is nonetheless performing
only pure computation and does not access these hypothetical memory
addresses; so despite appearances, it remains a valid program. Of
course, it's probably still not a good idea to work with pointers in
this way since it is all to easy to make a mistake.

Greg

Nov 22 '05 #9

P: n/a
In article <11**********************@g43g2000cwa.googlegroups .com>,
aling <li*********@126.com> wrote:
Now I understand. The result of &((struc*)0)->member2 is not offset, it
is a memory address, though it can be used as one offset.


Right, because structs have subobjects, and so -> effectively moves
to the subobject that is in the position where the respective memory
of the right type starts. IOWs, where that object's offsetof() is.
But, as mentioned, since there really is no such object at 0,
the code is undefined. Better to use offsetof() (although oddly
you may find it using the same implementation, but then at least
you'll know it works, and you'll be using offsetof() anyway
which will be portable so that if you use offsetof on an
implmentation where the undefined behavior is not doing the
obvious things, the vendor will provide for you the right definition
for that platform).
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Nov 22 '05 #10

P: n/a
In article <11**********************@g49g2000cwa.googlegroups .com>,
Greg <gr****@pacbell.net> wrote:
aling wrote:
Why the result of &((struc*)0)->member2 is a offset instead of address?

Why the two results of following code is different, and one is memory
address, the other is offset?

struct struc {
int member1;
int member2;
} astruc, * p_struc=&astruc, *p_null=0;
printf("&p_struc->member2=%p\n", &p_struc->member2); // this result is
a memory address
printf("&p_null->member2=%p\n", &p_null->member2); // this result is
offset of member2
The program is calculating the address of the member as if the object
itself were located at memory address 0. So addresses are identical to
offsets since they are both being measured from the same reference
point. Note that the memory address 0 as used in this program is not
necessarily the address that the NULL pointer references. And it is
even conceivable that memory address 0 could be a valid memory location
on a system somewhere. For that reason, the null pointer "0" is, in
C++, a symbolic representation of an invalid object address. The actual
null pointer address used when the code is compiled can be different
and would depend on the implementation.


This I believe is all correct.
And as alarming as this program appears, it is nonetheless performing
only pure computation and does not access these hypothetical memory
addresses; so despite appearances, it remains a valid program. Of
course, it's probably still not a good idea to work with pointers in
this way since it is all to easy to make a mistake.


The problem though as I recall it is that _the struct_ is not
at address 0. I know both the C and C++ committee looked at this
and recall that it remained undefined behavior. Am I not recalling
a change that was made upon looking at it?
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Nov 22 '05 #11

P: n/a
Greg Comeau wrote:

Better to use offsetof() (although oddly
you may find it using the same implementation, but then at least
you'll know it works


Indeed. It's not odd, because offsetof is in the standard library. The
standard library is part of the implementation, and the only requirement
is that its components do what they're supposed to do. They can, and
often do, rely on "undefined behavior" which sometimes is quite well
defined for a particular compiler.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Nov 22 '05 #12

P: n/a
In article <Mu********************@rcn.net>,
Pete Becker <pe********@acm.org> wrote:
Greg Comeau wrote:
Better to use offsetof() (although oddly
you may find it using the same implementation, but then at least
you'll know it works


Indeed. It's not odd, because offsetof is in the standard library. The
standard library is part of the implementation, and the only requirement
is that its components do what they're supposed to do. They can, and
often do, rely on "undefined behavior" which sometimes is quite well
defined for a particular compiler.


I was trying to say that a newbie may find it odd that a header
file can do something but that they are not necessarily supposed
to do it that same way, and it's worth emphasizing what you say again:
what you sometimes see in headers is for implementors so newbies
before using something that "looks cool" look it up or pass it by this NG.
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Nov 22 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.