Structure member offset.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • gokrix

    #1

    Structure member offset.

    #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

    #2
    Re: Structure member offset.

    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" <gokrix@hotmail .com> wrote in message
    news:43904025$1 @news.beasys.co m...[color=blue]
    > #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[/color]


    Comment

    • pemo

      #3
      Re: Structure member offset.


      "gokrix" <gokrix@hotmail .com> wrote in message
      news:43904025$1 @news.beasys.co m...[color=blue]
      > #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?[/color]

      [color=blue]
      > Which part of the standard mandates this behaviour?[/color]

      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));


      Comment

      • gokrix

        #4
        Re: Structure member offset.

        pemo wrote:[color=blue]
        > "gokrix" <gokrix@hotmail .com> wrote in message
        > news:43904025$1 @news.beasys.co m...
        >[color=green]
        >>#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?[/color]
        >
        >
        >[color=green]
        >>Which part of the standard mandates this behaviour?[/color]
        >
        >
        > 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));
        >
        >[/color]

        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

        Comment

        • pemo

          #5
          Re: Structure member offset.


          "gokrix" <gokrix@hotmail .com> wrote in message
          news:43904BC2.9 090805@hotmail. com...[color=blue]
          > pemo wrote:[color=green]
          >> "gokrix" <gokrix@hotmail .com> wrote in message
          >> news:43904025$1 @news.beasys.co m...
          >>[/color][/color]

          <snip>
          [color=blue]
          >
          > 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.[/color]

          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?


          Comment

          • Eric Sosman

            #6
            Re: Structure member offset.

            gokrix wrote:
            [color=blue]
            > #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?[/color]

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

            --
            Eric Sosman
            esosman@acm-dot-org.invalid

            Comment

            • gokrix

              #7
              Re: Structure member offset.

              pemo wrote:[color=blue]
              > "gokrix" <gokrix@hotmail .com> wrote in message
              > news:43904BC2.9 090805@hotmail. com...
              >[color=green]
              >>pemo wrote:
              >>[color=darkred]
              >>>"gokrix" <gokrix@hotmail .com> wrote in message
              >>>news:4390402 5$1@news.beasys .com...
              >>>[/color][/color]
              >
              >
              > <snip>
              >[color=green]
              >>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.[/color]
              >
              >
              > 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?
              >
              >[/color]

              Yes, indeed.

              Thanks,
              --GS

              Comment

              • Skarmander

                #8
                Re: Structure member offset.

                gokrix wrote:[color=blue]
                > pemo wrote:[color=green]
                >> "gokrix" <gokrix@hotmail .com> wrote in message
                >> news:43904BC2.9 090805@hotmail. com...
                >>[color=darkred]
                >>> pemo wrote:
                >>>
                >>>> "gokrix" <gokrix@hotmail .com> wrote in message
                >>>> news:43904025$1 @news.beasys.co m...
                >>>>[/color]
                >>
                >>
                >> <snip>
                >>[color=darkred]
                >>> 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.[/color]
                >>
                >>
                >> 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?
                >>[/color]
                >
                > Yes, indeed.
                >[/color]
                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.

                Comment

                • gokrix

                  #9
                  Re: Structure member offset.

                  Eric Sosman wrote:[color=blue]
                  > gokrix wrote:
                  >[color=green]
                  >> #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?[/color]
                  >
                  >
                  > No part of the Standard mandates this behavior.
                  > The behavior is undefined, meaning that the Standard
                  > permits anything at all to happen.
                  >[/color]

                  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

                  Comment

                  • Thad Smith

                    #10
                    Re: Structure member offset.

                    gokrix wrote:
                    [color=blue]
                    > Eric Sosman wrote:
                    >[color=green]
                    >> gokrix wrote:[color=darkred]
                    >>> printf("addr is [%p]. \n", &(((struct s*)0)->c));
                    >>> ...
                    >>> Which part of the standard mandates this behaviour?[/color]
                    >>
                    >> No part of the Standard mandates this behavior.
                    >> The behavior is undefined, meaning that the Standard
                    >> permits anything at all to happen.[/color]
                    >
                    > Hmph. I assumed it was ISO C because all three compilers I tried (Sun
                    > C, gcc, MSVC) returned identical results.[/color]

                    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

                    Comment

                    • Richard Tobin

                      #11
                      Re: Structure member offset.

                      In article <439053c4@news. beasys.com>, gokrix <gokrix@hotmail .com> wrote:
                      [color=blue][color=green]
                      >> No part of the Standard mandates this behavior.
                      >> The behavior is undefined, meaning that the Standard
                      >> permits anything at all to happen.[/color][/color]
                      [color=blue]
                      >Hmph. I assumed it was ISO C because all three compilers I tried (Sun
                      >C, gcc, MSVC) returned identical results.[/color]

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

                      -- Richard

                      Comment

                      Working...