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

Accessing structure members indirectly

P: n/a
Here is the code

int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}

Will the last printf always result in correct output? Is it safer to
access data members of structure this way?

Oct 27 '06 #1
Share this Question
Share on Google+
14 Replies


P: n/a
Kavya <Le******@gmail.comwrote:
Here is the code
int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}
Will the last printf always result in correct output? Is it safer to
access data members of structure this way?
You are guaranteed that address of the first element of a structure
is always at the address of the structure, so you can safely access
the member 'a' of your structure that way (if it's a good idea is
a totally different question). For the other members it's not safe,
e.g.

printf( "%d", * (int *) ((char *) ptr + sizeof(int)));

is _not_ guranteed to print out the value you stored in the member
'b' since the compiler is allowed to insert as many padding bytes
between the structure members as it likes.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Oct 27 '06 #2

P: n/a
Kavya wrote:
Here is the code

int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}

Will the last printf always result in correct output? Is it safer to
access data members of structure this way?
Why not just use an array instead of inventing convoluted ways to shoot
yourself in the foot?

Regards,
Bart.

Oct 27 '06 #3

P: n/a
"Kavya" <Le******@gmail.comwrote:
Here is the code

int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}

Will the last printf always result in correct output?
Yes, for the first member. The first member of a struct must always have
the same address as the struct itself. This is required by the Standard.
For any other member, you don't know that. There could be padding
between a and b, so ((int *)&s)+1 might not point at s.b.
Is it safer to access data members of structure this way?
Not at all. Accessing them normally is the best way.

Richard
Oct 27 '06 #4

P: n/a
In article <11**********************@b28g2000cwb.googlegroups .com>,
Kavya <Le******@gmail.comwrote:
>Here is the code
>int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}
>Will the last printf always result in correct output?
You haven't defined what output it is that you feel to be "correct".
>Is it safer to
access data members of structure this way?
Safer than what??

What the C standards say is that:

1) the first named member of the structure will always be at offset 0
from the beginning of the structure

2) each additional member will be placed in increasing address order

3) there may be internal padding at any point after the first member,
including at the end of the structure

4) bitfields generally follow the increasing address rule, but the order
of the bits within the internal storage allocation size that
the implementation uses for bitfields, is up to the implementation
5) special meaning for a bitfield width of 0
The first rule ensures that in your example *(int *)&s corresponds
to s.a. However, *(1 + (int *)&s) will *not* necessarily be s.b
because of rule 3.

--
There are some ideas so wrong that only a very intelligent person
could believe in them. -- George Orwell
Oct 27 '06 #5

P: n/a

Thanks alot everyone.

Oct 27 '06 #6

P: n/a
Kavya <Le******@gmail.comwrote:
int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}
Will the last printf always result in correct output?
No, but only because it is implementation-defined whether a newline
is required after the last line of output:

printf("%d\n",*(int*)ptr);

P.S. Main returns int, but you didn't return one. Do so and make your
execution environment happy.

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Oct 27 '06 #7

P: n/a

Christopher Benson-Manica wrote:
Kavya <Le******@gmail.comwrote:
int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}
Will the last printf always result in correct output?

No, but only because it is implementation-defined whether a newline
is required after the last line of output:
Sorry. I didn't get that.
P.S. Main returns int, but you didn't return one. Do so and make your
execution environment happy.
Isn't that implicit?

Oct 27 '06 #8

P: n/a
Kavya <Le******@gmail.comwrote:
No, but only because it is implementation-defined whether a newline
is required after the last line of output:
Sorry. I didn't get that.
The English version of that sentence is "Things might not work like
you expect if you don't end your output with a newline."
P.S. Main returns int, but you didn't return one. Do so and make your
execution environment happy.
Isn't that implicit?
Only in C99; you are probably not using a C99 compiler. (In English:
There are two different standards that govern the C language - C89 and
C99; many or most C compilers conform to C89 rather than C99. In C89,
if you fail to return a value from main, your shell or whatever you're
executing your program in gets a random return value.)

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Oct 27 '06 #9

P: n/a

Christopher Benson-Manica wrote:
Kavya <Le******@gmail.comwrote:
No, but only because it is implementation-defined whether a newline
is required after the last line of output:
Sorry. I didn't get that.

The English version of that sentence is "Things might not work like
you expect if you don't end your output with a newline."
P.S. Main returns int, but you didn't return one. Do so and make your
execution environment happy.
Isn't that implicit?

Only in C99; you are probably not using a C99 compiler. (In English:
There are two different standards that govern the C language - C89 and
C99; many or most C compilers conform to C89 rather than C99. In C89,
if you fail to return a value from main, your shell or whatever you're
executing your program in gets a random return value.)
Thanks for the these pointers.

Oct 27 '06 #10

P: n/a
Kavya wrote:
Here is the code

int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}

Will the last printf always result in correct output? Is it safer to
access data members of structure this way?
is offsetof() any use to you? I'm not sure what you are trying to do.
--
Nick Keighley

And so when you think of the future,
imagine a Pentium stamping on a man's face,
forever.

Oct 27 '06 #11

P: n/a
On Fri, 2006-10-27 at 02:56 -0700, Kavya wrote:
Here is the code

int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}

Will the last printf always result in correct output? Is it safer to
access data members of structure this way?
I'm pretty sure that "(int) *ptr" will be equally valid and predictable.
Unfortunately, neither /is/ predictable, so it depends on what you mean
by "correct" output.

I believe there is no undefined behaviour, which may be a good
definition of "correct". (Of course, I could be wrong.)

--
Andrew Poelstra <http://www.wpsoftware.net/projects/>

Oct 27 '06 #12

P: n/a
On Fri, 2006-10-27 at 15:18 +0000, Andrew Poelstra wrote:
On Fri, 2006-10-27 at 02:56 -0700, Kavya wrote:
Here is the code

int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}

Will the last printf always result in correct output? Is it safer to
access data members of structure this way?
<snip my own incorrectness>
>
I missed your struct definition above. Yes, this is in fact correct and
predictable, but only for the first element. (As has been noted by
others.)

--
Andrew Poelstra <http://www.wpsoftware.net/projects/>

Oct 27 '06 #13

P: n/a
Andrew Poelstra <ap*******@false.sitewrites:
On Fri, 2006-10-27 at 02:56 -0700, Kavya wrote:
>Here is the code

int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}

Will the last printf always result in correct output? Is it safer to
access data members of structure this way?

I'm pretty sure that "(int) *ptr" will be equally valid and predictable.
Unfortunately, neither /is/ predictable, so it depends on what you mean
by "correct" output.
*ptr is of type struct node; you can't convert a struct value to int.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 27 '06 #14

P: n/a
Ark
Jens Thoms Toerring wrote:
Kavya <Le******@gmail.comwrote:
>Here is the code
>int main(){
struct node{
int a;
int b;
int c;
};
struct node s={3,5,6};
struct node *ptr=&s;
printf("%d",*(int*)ptr);
}
>Will the last printf always result in correct output? Is it safer to
access data members of structure this way?

You are guaranteed that address of the first element of a structure
is always at the address of the structure, so you can safely access
the member 'a' of your structure that way (if it's a good idea is
a totally different question). For the other members it's not safe,
e.g.

printf( "%d", * (int *) ((char *) ptr + sizeof(int)));

is _not_ guranteed to print out the value you stored in the member
'b' since the compiler is allowed to insert as many padding bytes
between the structure members as it likes.
However, b can be portably printed using
printf("%d", *(int*)((char*)ptr + offsetof(struct node, b)));

As to the wisdom of this technique... Occasionally, one may need/want to
parse data consisting of "derived types" like
struct type1 {
int RTTI;
struct base_t base;
struct type1_specific more;
};
struct type3 {
int RTTI;
struct base_t base;
struct type3_specific more;
};
Here, an offsetof-based technique may be useful.

- Ark
Oct 28 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.