Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Structure member offset.

Reply
Thread Tools

Structure member offset.

 
 
gokrix
Guest
Posts: n/a
 
      12-02-2005
#include <stdio.h>
#include <stdlib.h>

struct s
{
int i;
char c;
float f;
};

int main()
{
printf("addr is [%p]. \n", &(((struct s*)0)->c));
return EXIT_SUCCESS;
}

When I compile (gcc -g -W -Wall -ansi -pedantic) and run the above code,
it prints "addr is [0x4].". If I change to 0 to 100, it prints 104.

Why?

Which part of the standard mandates this behaviour?

Thanks,
--GS
 
Reply With Quote
 
 
 
 
Raghu
Guest
Posts: n/a
 
      12-02-2005
The answer you are getting is correct , becuase in the structure first
element is of integer type , so the "char c " lies 4 bytes away from the
base address you give.
if you interchange position of float f and char c in your structure , the
offset for char c will be 8 from the base address you give.

-Raghu.

"gokrix" <(E-Mail Removed)> wrote in message
news:43904025$(E-Mail Removed)...
> #include <stdio.h>
> #include <stdlib.h>
>
> struct s
> {
> int i;
> char c;
> float f;
> };
>
> int main()
> {
> printf("addr is [%p]. \n", &(((struct s*)0)->c));
> return EXIT_SUCCESS;
> }
>
> When I compile (gcc -g -W -Wall -ansi -pedantic) and run the above code,
> it prints "addr is [0x4].". If I change to 0 to 100, it prints 104.
>
> Why?
>
> Which part of the standard mandates this behaviour?
>
> Thanks,
> --GS



 
Reply With Quote
 
 
 
 
pemo
Guest
Posts: n/a
 
      12-02-2005

"gokrix" <(E-Mail Removed)> wrote in message
news:43904025$(E-Mail Removed)...
> #include <stdio.h>
> #include <stdlib.h>
>
> struct s
> {
> int i;
> char c;
> float f;
> };
>
> int main()
> {
> printf("addr is [%p]. \n", &(((struct s*)0)->c));
> return EXIT_SUCCESS;
> }
>
> When I compile (gcc -g -W -Wall -ansi -pedantic) and run the above code,
> it prints "addr is [0x4].". If I change to 0 to 100, it prints 104.
>
> Why?



> Which part of the standard mandates this behaviour?


The logic bit

You're using 0 -or- 100 as an address, and then casting that to struct s
pointer. You then take the address of the member 'c' - which comes after
member 'i'. i is an int, and appears to be 32-bits with your compiler.
32-bits = 4 bytes. So, addresses 0, 1, 2, 3 are 'i', and therefore 'c'
starts at 4.

Presumably, you actually want a struct s, e.g.,

struct s j;

printf("addr is [%p]. \n", &(((struct s*)&j)->c));


 
Reply With Quote
 
gokrix
Guest
Posts: n/a
 
      12-02-2005
pemo wrote:
> "gokrix" <(E-Mail Removed)> wrote in message
> news:43904025$(E-Mail Removed)...
>
>>#include <stdio.h>
>>#include <stdlib.h>
>>
>>struct s
>>{
>> int i;
>> char c;
>> float f;
>>};
>>
>>int main()
>>{
>> printf("addr is [%p]. \n", &(((struct s*)0)->c));
>> return EXIT_SUCCESS;
>>}
>>
>>When I compile (gcc -g -W -Wall -ansi -pedantic) and run the above code,
>>it prints "addr is [0x4].". If I change to 0 to 100, it prints 104.
>>
>>Why?

>
>
>
>>Which part of the standard mandates this behaviour?

>
>
> The logic bit
>
> You're using 0 -or- 100 as an address, and then casting that to struct s
> pointer. You then take the address of the member 'c' - which comes after
> member 'i'. i is an int, and appears to be 32-bits with your compiler.
> 32-bits = 4 bytes. So, addresses 0, 1, 2, 3 are 'i', and therefore 'c'
> starts at 4.
>
> Presumably, you actually want a struct s, e.g.,
>
> struct s j;
>
> printf("addr is [%p]. \n", &(((struct s*)&j)->c));
>
>


Maybe I could have framed the question better, along the lines of "Why
is this not an undefined operation?". I was under the impression that
the '->' operation on an address that does not belong to you (say a
random address like 0 or 100) leads to undefined behaviour.

Thanks,
--GS
 
Reply With Quote
 
pemo
Guest
Posts: n/a
 
      12-02-2005

"gokrix" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> pemo wrote:
>> "gokrix" <(E-Mail Removed)> wrote in message
>> news:43904025$(E-Mail Removed)...
>>


<snip>

>
> Maybe I could have framed the question better, along the lines of "Why is
> this not an undefined operation?". I was under the impression that the
> '->' operation on an address that does not belong to you (say a random
> address like 0 or 100) leads to undefined behaviour.


Well, yes it does - unless you know what's at address 0, 100 etc.

Were you expecting a seg fault, or a compiler diagnostic, or something else?


 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-02-2005
gokrix wrote:

> #include <stdio.h>
> #include <stdlib.h>
>
> struct s
> {
> int i;
> char c;
> float f;
> };
>
> int main()
> {
> printf("addr is [%p]. \n", &(((struct s*)0)->c));
> return EXIT_SUCCESS;
> }
>
> When I compile (gcc -g -W -Wall -ansi -pedantic) and run the above code,
> it prints "addr is [0x4].". If I change to 0 to 100, it prints 104.
>
> Why?
>
> Which part of the standard mandates this behaviour?


No part of the Standard mandates this behavior.
The behavior is undefined, meaning that the Standard
permits anything at all to happen.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid

 
Reply With Quote
 
gokrix
Guest
Posts: n/a
 
      12-02-2005
pemo wrote:
> "gokrix" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>
>>pemo wrote:
>>
>>>"gokrix" <(E-Mail Removed)> wrote in message
>>>news:43904025$(E-Mail Removed)...
>>>

>
>
> <snip>
>
>>Maybe I could have framed the question better, along the lines of "Why is
>>this not an undefined operation?". I was under the impression that the
>>'->' operation on an address that does not belong to you (say a random
>>address like 0 or 100) leads to undefined behaviour.

>
>
> Well, yes it does - unless you know what's at address 0, 100 etc.
>
> Were you expecting a seg fault, or a compiler diagnostic, or something else?
>
>


Yes, indeed.

Thanks,
--GS
 
Reply With Quote
 
gokrix
Guest
Posts: n/a
 
      12-02-2005
Eric Sosman wrote:
> gokrix wrote:
>
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> struct s
>> {
>> int i;
>> char c;
>> float f;
>> };
>>
>> int main()
>> {
>> printf("addr is [%p]. \n", &(((struct s*)0)->c));
>> return EXIT_SUCCESS;
>> }
>>
>> When I compile (gcc -g -W -Wall -ansi -pedantic) and run the above
>> code, it prints "addr is [0x4].". If I change to 0 to 100, it prints
>> 104.
>>
>> Why?
>>
>> Which part of the standard mandates this behaviour?

>
>
> No part of the Standard mandates this behavior.
> The behavior is undefined, meaning that the Standard
> permits anything at all to happen.
>


Hmph. I assumed it was ISO C because all three compilers I tried (Sun
C, gcc, MSVC) returned identical results.

Bastard compiler writers. Do they have a union?

Thanks,
--GS
 
Reply With Quote
 
Skarmander
Guest
Posts: n/a
 
      12-02-2005
gokrix wrote:
> pemo wrote:
>> "gokrix" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>>
>>> pemo wrote:
>>>
>>>> "gokrix" <(E-Mail Removed)> wrote in message
>>>> news:43904025$(E-Mail Removed)...
>>>>

>>
>>
>> <snip>
>>
>>> Maybe I could have framed the question better, along the lines of
>>> "Why is this not an undefined operation?". I was under the
>>> impression that the '->' operation on an address that does not belong
>>> to you (say a random address like 0 or 100) leads to undefined
>>> behaviour.

>>
>>
>> Well, yes it does - unless you know what's at address 0, 100 etc.
>>
>> Were you expecting a seg fault, or a compiler diagnostic, or something
>> else?
>>

>
> Yes, indeed.
>

Valuable lesson, then: undefined behavior can be anything, including doing
something meaningful.

Evaluating &(((struct s*)0)->c) will not cause a segmentation fault because
gcc sees that this expression has a constant value. It doesn't need to
access any memory to compute it, and therefore it won't.

Change it to ((struct s*)0)->c, however, and you will see a quite different
result on most platforms.

Finally, if you want to know the offset of a struct member in a portable
way, use offsetof().

S.
 
Reply With Quote
 
Thad Smith
Guest
Posts: n/a
 
      12-02-2005
gokrix wrote:

> Eric Sosman wrote:
>
>> gokrix wrote:
>>> printf("addr is [%p]. \n", &(((struct s*)0)->c));
>>> ...
>>> Which part of the standard mandates this behaviour?

>>
>> No part of the Standard mandates this behavior.
>> The behavior is undefined, meaning that the Standard
>> permits anything at all to happen.

>
> Hmph. I assumed it was ISO C because all three compilers I tried (Sun
> C, gcc, MSVC) returned identical results.


Getting identical results on 3 compiler/target combinations is a poor
predictor of standard behavior. Forexample, most current processors use
two's complement representation and power-of-two bit length integers,
but code depending on that would not be standard-conforming. Reading
the standard is the best way to determine standard behavior.

--
Thad

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Difference between c structure and c++ structure raghunandan_1081@yahoo.com C++ 9 11-11-2011 07:34 AM
Memory allocation in Structure to Structure pra_ramli@rediffmail.com C++ 2 03-09-2006 05:51 AM
Copy String structure "A" to string structure "B" Leo Nunez C Programming 3 02-09-2005 05:14 AM
Pointers to structure and array of structure. Excluded_Middle C Programming 4 10-26-2004 05:39 AM
How would I use qsort to sort a struct with a char* member and a long member - I want to sort in order of the long member Angus Comber C Programming 7 02-05-2004 06:41 PM



Advertisments