problem with a casted pointer

P

praveen

-------------------------------My dud
program------------------------------------------
#include <stdioi.h>
#include <stddef.h>

typedef struct dummy{
int x, y, z;
}point;

int main() {
point a = {1, 2, 3};
int *p = (int *)(&a + offsetof(point, y);
int *q = (int *)(&a + offsetof(point, z);
printf("%d %d", *p, *q);
return 0;
}
 
M

mark_bluemel

-------------------------------My dud
program------------------------------------------
#include <stdioi.h>
#include <stddef.h>

typedef struct dummy{
int x, y, z;

}point;

int main() {
point a = {1, 2, 3};
int *p = (int *)(&a + offsetof(point, y);

&a is a pointer to point, so adding offsetof(point,y) will move it on
"n" points, not "n" bytes. You're now into Undefined Behaviour...
int *q = (int *)(&a + offsetof(point, z);

As above.
printf("%d %d", *p, *q);
return 0;}

-------------------------------------------------------------------------------------------------
my question is will *p and *q really point to (a.x) and (a.y) ?
No.

i ran this program on DevC++ 4.9.9.2 and i'm getting some garbage
values as output!!!

I'm not surprised.

What are you actually trying to do? Why won't (e.g.) "&a.y" do what
you need?

By the way, it's _much_ better to cut and paste your real code, rather
than type up an approximation. "stdioi.h" doesn't exist and you have
missing parentheses in your code.
 
E

Eric Sosman

praveen said:
-------------------------------My dud
program------------------------------------------
#include <stdioi.h>

I wish, I *wish*, I *REALLY* *WISH* that when people
post "this is my code" they would actually post their code
and not some half-baked, typo-ridden approximation! You're
just introducing extra bugs that divert attention from the
problem that's actually bothering you; is that wise?
#include <stddef.h>

typedef struct dummy{
int x, y, z;
}point;

int main() {
point a = {1, 2, 3};
int *p = (int *)(&a + offsetof(point, y);

Syntax error. If corrected, probably undefined behavior.
int *q = (int *)(&a + offsetof(point, z);

Syntax error. If corrected, definitely undefined behavior.
(No, I won't explain why one is "probably" the other "definitely,"
because I'm angry with you. See above.)
printf("%d %d", *p, *q);

Definitely undefined behavior (twice, or possibly thrice).
(No, I won't explain the "thrice." See above.)
return 0;
}

No, never.
i ran this program on DevC++ 4.9.9.2 and i'm getting some garbage
values as output!!!

You mean, after the required compiler diagnostics about
the syntax errors and the (probably) non-existent header?
If you ever expect to become a programmer, you *must* learn
how to ask questions without distorting the facts!

<Relenting> You have overlooked a basic fact about pointer
arithmetic: Adding an integer to a pointer "steps" it in whole
units of the pointed-to type. Now, ask yourself the question:
"What is the type of the pointer value `&a'?"
 
A

Army1987

Eric Sosman said:
I wish, I *wish*, I *REALLY* *WISH* that when people
post "this is my code" they would actually post their code
and not some half-baked, typo-ridden approximation! You're
just introducing extra bugs that divert attention from the
problem that's actually bothering you; is that wise?


Syntax error. If corrected, probably undefined behavior.


Syntax error. If corrected, definitely undefined behavior.
(No, I won't explain why one is "probably" the other "definitely,"
because I'm angry with you. See above.)

Because, if sizeof a.x == 1 and there's no padding, then
offsetof(point, y) is 1, so p points right past the end of the
fictitious one-element array of point a can be thought to belong
to. Right?
Definitely undefined behavior (twice, or possibly thrice).
(No, I won't explain the "thrice." See above.)

Because it is implementation-defined wheter text files (including
stdout) need to end with a newline?
 
E

Eric Sosman

Army1987 wrote On 06/29/07 09:01,:
Because, if sizeof a.x == 1 and there's no padding, then
offsetof(point, y) is 1, so p points right past the end of the
fictitious one-element array of point a can be thought to belong
to. Right?

Give that man a cigar!
Because it is implementation-defined wheter text files (including
stdout) need to end with a newline?

Oops! I missed that one. Give *this* man a Bronx cheer!
 
A

Army1987

Eric Sosman said:
Army1987 wrote On 06/29/07 09:01,:

Give that man a cigar!


Oops! I missed that one. Give *this* man a Bronx cheer!

Ah... Then the "thrice" was... now I get it...

"Possibly" because we don't know that an implementation does not have a <stdioi.h> header which in turn includes <stdio.h>, so we
don't know for sure that we're calling a variadic function without
a prototype in scope?
 
E

Eric Sosman

Army1987 wrote On 06/29/07 11:05,:
Ah... Then the "thrice" was... now I get it...

"Possibly" because we don't know that an implementation does not have a <stdioi.h> header which in turn includes <stdio.h>, so we
don't know for sure that we're calling a variadic function without
a prototype in scope?

Give that man another cigar! (Y'know, you really
should cut down: Those things are bad for you.)
 
J

Joe Wright

Eric said:
Army1987 wrote On 06/29/07 09:01,:

Give that man a cigar!


Oops! I missed that one. Give *this* man a Bronx cheer!
How about..

int *p = (int*)((char*)&a + offsetof(point,x));

...it seems to work but is it correct?
 
C

CBFalconer

praveen said:
#include <stdioi.h>
#include <stddef.h>

typedef struct dummy{
int x, y, z;
}point;

int main() {
point a = {1, 2, 3};
int *p = (int *)(&a + offsetof(point, y);
int *q = (int *)(&a + offsetof(point, z);
printf("%d %d", *p, *q);
return 0;
}

my question is will *p and *q really point to (a.x) and (a.y) ?
i ran this program on DevC++ 4.9.9.2 and i'm getting some garbage
values as output!!!

No. *p points to a.y, and *q points to a.z. Remove the casts,
they are unnecessary and only serve to suppress compiler warnings.
Use "int main(void)", a better expression. There is no such thing
as stdioi.h. You want stdio.h.
 
A

Army1987

CBFalconer said:
No. *p points to a.y, and *q points to a.z.
They don't. And they still wouldn't if we added right parentheses
before two semicolons.

What type is &a? What is &a + 1?
 
K

Keith Thompson

CBFalconer said:
No. *p points to a.y, and *q points to a.z. Remove the casts,
they are unnecessary and only serve to suppress compiler warnings.
Use "int main(void)", a better expression. There is no such thing
as stdioi.h. You want stdio.h.

No, *p and *q are of type int, and they don't point to anything.
(I think you just forgot to drop the '*' characters.)

But p and q don't point to a.y and a.z anyway; see the other
responses.
 
H

helloguys

-------------------------------My dud
program------------------------------------------
#include <stdioi.h>
#include <stddef.h>

typedef struct dummy{
int x, y, z;

}point;

int main() {
point a = {1, 2, 3};
int *p = (int *)(&a + offsetof(point, y);
int *q = (int *)(&a + offsetof(point, z);
printf("%d %d", *p, *q);
return 0;}




i think you made a misunderstand of *a* and *&a*;
*a* is the begin address of the struct ,
and &a is a pointer who point to the address a, if sizeof(a)=12 (no
padding)
then &a +2 =a+2*12 and is beyond the struct a, so you got the garbage
output.
 
P

praveen

&a is a pointer to point, so adding offsetof(point,y) will move it on
"n" points, not "n" bytes. You're now into Undefined Behaviour...


As above.



I'm not surprised.

What are you actually trying to do? Why won't (e.g.) "&a.y" do what
you need?

By the way, it's _much_ better to cut and paste your real code, rather
than type up an approximation. "stdioi.h" doesn't exist and you have
missing parentheses in your code.
actually i used <stdio.h> in my code but <stdioi.h> is a typo just
replace it with stdio.h
 
F

Flash Gordon

praveen wrote, On 19/07/07 07:57:
On Jun 29, 4:32 pm, (e-mail address removed) wrote:

actually i used <stdio.h> in my code but <stdioi.h> is a typo just
replace it with stdio.h

That is precisely why Mark said that you should copy and paste. It was
obvious that that error was a typo, but how many other errors in the
code you posted were typos rather than errors in your real code?

NEVER retype your code, ALWAYS copy and paste it in to your posts. That
way people will be able to see your code errors rather than your typing
errors.
 
D

David Thompson

On Fri, 29 Jun 2007 12:36:20 -0400, Joe Wright
How about..

int *p = (int*)((char*)&a + offsetof(point,x));

..it seems to work but is it correct?

Since no one else has actually confirmed this yet ...

yes. At least technically, i.e. it portably computes the correct
address, with the correct type.

It is ugly; and fragile, hence hard to maintain; and thus not a good
design choice unless really needed. Using a.x, and &a.x, etc., is as
already noted preferable whenever (reasonably) possible.

Aside: for x in particular, since it is the first member in the
example, its offset is (always) 0 and just
int * p = (int*) & a;
is fine. But I took the question to be, as it usually is, about an
arbitrary member, not (necessarily) the first.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top