Structure member offset.

Discussion in 'C Programming' started by gokrix, Dec 2, 2005.

  1. gokrix

    gokrix Guest

    #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
     
    gokrix, Dec 2, 2005
    #1
    1. Advertising

  2. gokrix

    Raghu Guest

    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" <> wrote in message
    news:43904025$...
    > #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
     
    Raghu, Dec 2, 2005
    #2
    1. Advertising

  3. gokrix

    pemo Guest

    "gokrix" <> wrote in message
    news:43904025$...
    > #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));
     
    pemo, Dec 2, 2005
    #3
  4. gokrix

    gokrix Guest

    pemo wrote:
    > "gokrix" <> wrote in message
    > news:43904025$...
    >
    >>#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
     
    gokrix, Dec 2, 2005
    #4
  5. gokrix

    pemo Guest

    "gokrix" <> wrote in message
    news:...
    > pemo wrote:
    >> "gokrix" <> wrote in message
    >> news:43904025$...
    >>


    <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?
     
    pemo, Dec 2, 2005
    #5
  6. gokrix

    Eric Sosman Guest

    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
    lid
     
    Eric Sosman, Dec 2, 2005
    #6
  7. gokrix

    gokrix Guest

    pemo wrote:
    > "gokrix" <> wrote in message
    > news:...
    >
    >>pemo wrote:
    >>
    >>>"gokrix" <> wrote in message
    >>>news:43904025$...
    >>>

    >
    >
    > <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
     
    gokrix, Dec 2, 2005
    #7
  8. gokrix

    gokrix Guest

    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
     
    gokrix, Dec 2, 2005
    #8
  9. gokrix

    Skarmander Guest

    gokrix wrote:
    > pemo wrote:
    >> "gokrix" <> wrote in message
    >> news:...
    >>
    >>> pemo wrote:
    >>>
    >>>> "gokrix" <> wrote in message
    >>>> news:43904025$...
    >>>>

    >>
    >>
    >> <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.
     
    Skarmander, Dec 2, 2005
    #9
  10. gokrix

    Thad Smith Guest

    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
     
    Thad Smith, Dec 2, 2005
    #10
  11. In article <>, gokrix <> wrote:

    >> 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.


    Undefined behaviour includes the possibility of doing the obvious,
    straightforward thing.

    -- Richard
     
    Richard Tobin, Dec 2, 2005
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lance Riedel

    Translated Offset to Source Offset

    Lance Riedel, Oct 14, 2003, in forum: XML
    Replies:
    2
    Views:
    502
    Patrick TJ McPhee
    Oct 15, 2003
  2. junky_fellow

    offset of a member inside a structure

    junky_fellow, Oct 14, 2004, in forum: C Programming
    Replies:
    15
    Views:
    992
    Tim Rentsch
    Oct 24, 2004
  3. Replies:
    10
    Views:
    1,116
    Keith Thompson
    Jun 23, 2005
  4. RAKHE

    OFFSET of Structure Member

    RAKHE, Jun 24, 2010, in forum: C Programming
    Replies:
    8
    Views:
    3,456
  5. Roy Smith
    Replies:
    4
    Views:
    276
    Roy Smith
    Jan 27, 2013
Loading...

Share This Page