Where do pointers point to?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • x-pander

    Where do pointers point to?

    Is is guaranteed, that a pointer to any object in C points exactly at the
    lowest addressed byte of this object?

    Specifcally is it possible for any platform/os/compiler combination that:
    (char *)v != (void *)v
    where v is an int variable for example.

    If so, any real-life examples?



  • Ben Pfaff

    #2
    Re: Where do pointers point to?

    "x-pander" <ngclc@pitek.eu .org> writes:
    [color=blue]
    > Is is guaranteed, that a pointer to any object in C points exactly at the
    > lowest addressed byte of this object?[/color]

    Yes, as far as I know. (I'd love to hear intelligent
    disagreement on this, because I'd learn from it.)
    [color=blue]
    > Specifcally is it possible for any platform/os/compiler combination that:
    > (char *)v != (void *)v
    > where v is an int variable for example.[/color]

    Non sequitur: you just dragged in integer-to-pointer conversion,
    which is definitely non-portable.
    --
    "Give me a couple of years and a large research grant,
    and I'll give you a receipt." --Richard Heathfield

    Comment

    • x-pander

      #3
      Re: Where do pointers point to?

      > Specifcally is it possible for any platform/os/compiler combination that:[color=blue]
      > (char *)v != (void *)v
      > where v is an int variable for example.[/color]

      CORRECTION, of course (!!!) i meant:
      (char *)&v != (void *)&v


      Comment

      • Christian Bau

        #4
        Re: Where do pointers point to?

        In article <cs1rtm$1irl$1@ mamut.aster.pl> ,
        "x-pander" <ngclc@pitek.eu .org> wrote:
        [color=blue]
        > Is is guaranteed, that a pointer to any object in C points exactly at the
        > lowest addressed byte of this object?
        >
        > Specifcally is it possible for any platform/os/compiler combination that:
        > (char *)v != (void *)v
        > where v is an int variable for example.[/color]

        A pointer points to the whole object.

        If you cast a pointer to another type, lets say from double* to int*,
        you get a pointer to an object that starts at the same place as the
        first object. So if you cast a pointer to char*, it points to the first
        byte of the object.

        You cannot compare char* and void*. In your example, the compiler will
        convert the (void *) v automatically to char*, so you are actually
        comparing

        (char *)v == (char *) (void *) v

        which is guaranteed to be equal.

        Comment

        • Christian Bau

          #5
          Re: Where do pointers point to?

          In article <87wtujpit3.fsf @benpfaff.org>,
          Ben Pfaff <blp@cs.stanfor d.edu> wrote:
          [color=blue]
          > "x-pander" <ngclc@pitek.eu .org> writes:
          >[color=green]
          > > Is is guaranteed, that a pointer to any object in C points exactly at the
          > > lowest addressed byte of this object?[/color]
          >
          > Yes, as far as I know. (I'd love to hear intelligent
          > disagreement on this, because I'd learn from it.)[/color]

          It points to the "first" byte. The C Standard doesn't say anything about
          addresses.

          So if you have

          int x;
          char* p = (char *) &x;

          then the bytes of x are p [0], p [1], ..., p [sizeof (int) - 1], and not
          for example p [0], p [-1], p [-2] and so on.

          However, imagine you have an application of 10 million lines of code,
          non-portable because it is written under the assumption that your
          hardware is bigendian. You need to make it run on littleendian hardware.
          You have the source code to the compiler. Instead of changing 10 million
          lines of code, change the compiler so that the "first" byte is at a
          higher address than the last byte; where "p++;" would usually be
          translated into a hardware instruction that adds sizeof (*p), it will be
          translated to a hardware instruction that subtracts sizeof (*p). Pointer
          comparisons say that p < q if a hardware compare instruction says p > q
          and so on. Now a pointer always points to the highest addressed byte,
          and it is completely conforming and invisible to the programmer. The
          compiler turned a littleendian hardware into a bigendian implementation.
          (Code that casts pointers to unsigned int and checks the last bits for
          alignment will not work anymore; casting to and from integer will
          generally give strange results).

          Comment

          • x-pander

            #6
            Re: Where do pointers point to?

            > If you cast a pointer to another type, lets say from double* to int*,[color=blue]
            > you get a pointer to an object that starts at the same place as the
            > first object. So if you cast a pointer to char*, it points to the first
            > byte of the object.[/color]

            I undesrtand that.
            [color=blue]
            > You cannot compare char* and void*. In your example, the compiler will
            > convert the (void *) v automatically to char*, so you are actually
            > comparing
            >
            > (char *)v == (char *) (void *) v
            >
            > which is guaranteed to be equal.[/color]

            So how about the result of the following comparision,
            which i think has a potential of effectively answering my original question:

            (int *)(char *)&v != &v




            Comment

            • Keith Thompson

              #7
              Re: Where do pointers point to?

              Christian Bau <christian.bau@ cbau.freeserve. co.uk> writes:[color=blue]
              > In article <87wtujpit3.fsf @benpfaff.org>,
              > Ben Pfaff <blp@cs.stanfor d.edu> wrote:
              >[color=green]
              >> "x-pander" <ngclc@pitek.eu .org> writes:
              >>[color=darkred]
              >> > Is is guaranteed, that a pointer to any object in C points exactly at the
              >> > lowest addressed byte of this object?[/color]
              >>
              >> Yes, as far as I know. (I'd love to hear intelligent
              >> disagreement on this, because I'd learn from it.)[/color]
              >
              > It points to the "first" byte. The C Standard doesn't say anything about
              > addresses.[/color]

              Sure it does. Just one example, C99 6.5.3.1p3:

              The unary & operator returns the address of its operand.

              --
              Keith Thompson (The_Other_Keit h) kst-u@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.

              Comment

              • x-pander

                #8
                Re: Where do pointers point to?

                > It points to the "first" byte. The C Standard doesn't say anything about[color=blue]
                > addresses.[/color]

                Actually it does:
                C99: 6.3.2.3.7
                "When a pointer to an object is converted to a pointer to a character type,
                the result points to the lowest addressed byte of the object. Successive
                increments of the result, up to the size of the object, yield pointers to
                the remaining bytes of the object."
                [color=blue]
                > You need to make it run on littleendian hardware.
                > You have the source code to the compiler. Instead of changing 10 million
                > lines of code, change the compiler so that the "first" byte is at a
                > higher address than the last byte; where "p++;" would usually be
                > translated into a hardware instruction that adds sizeof (*p), it will be
                > translated to a hardware instruction that subtracts sizeof (*p). Pointer
                > comparisons say that p < q if a hardware compare instruction says p > q
                > and so on. Now a pointer always points to the highest addressed byte,
                > and it is completely conforming and invisible to the programmer.[/color]

                An example situation in described system could be:

                int x;
                &x == 0x4003
                (void *)&x == 0x4003
                (char *)&x == 0x4000
                (void *)(char *)&x = 0x4000

                So:
                (void *)&x != (void *)(char *)&x

                In effect the following code would break (i've seen similar code in some
                libraries):

                void zero(void *ptr, int size)
                {
                memset(ptr, 0, size);
                }
                main()
                {
                int v;
                zero(&v, sizeof(v));
                }

                The solution is to always use char * instead of void *.

                Am I right?


                Comment

                • x-pander

                  #9
                  Re: Where do pointers point to?

                  > It points to the "first" byte. The C Standard doesn't say anything about[color=blue]
                  > addresses.[/color]

                  Actually it does:
                  C99: 6.3.2.3.7
                  "When a pointer to an object is converted to a pointer to a character type,
                  the result points to the lowest addressed byte of the object. Successive
                  increments of the result, up to the size of the object, yield pointers to
                  the remaining bytes of the object."
                  [color=blue]
                  > You need to make it run on littleendian hardware.
                  > You have the source code to the compiler. Instead of changing 10 million
                  > lines of code, change the compiler so that the "first" byte is at a
                  > higher address than the last byte; where "p++;" would usually be
                  > translated into a hardware instruction that adds sizeof (*p), it will be
                  > translated to a hardware instruction that subtracts sizeof (*p). Pointer
                  > comparisons say that p < q if a hardware compare instruction says p > q
                  > and so on. Now a pointer always points to the highest addressed byte,
                  > and it is completely conforming and invisible to the programmer.[/color]

                  An example situation in described system could be:

                  int x;
                  &x == 0x4003
                  (void *)&x == 0x4003
                  (char *)&x == 0x4000
                  (void *)(char *)&x = 0x4000

                  So:
                  (void *)&x != (void *)(char *)&x

                  In effect the following code would break (i've seen similar code in some
                  libraries):

                  void zero(void *ptr, int size)
                  {
                  memset(ptr, 0, size);
                  }
                  main()
                  {
                  int v;
                  zero(&v, sizeof(v));
                  }

                  The solution is to always use char * instead of void *.

                  Am I right?



                  Comment

                  • italy

                    #10
                    Re: Where do pointers point to?

                    You're cute, Ben Pfaff!

                    Comment

                    • Eric Sosman

                      #11
                      Re: Where do pointers point to?

                      x-pander wrote:[color=blue]
                      >
                      > So how about the result of the following comparision,
                      > which i think has a potential of effectively answering my original question:
                      >
                      > (int *)(char *)&v != &v[/color]

                      Guaranteed to work (evaluating to 0) if `v' is an `int'.

                      Potential undefined behavior if `v' is not an `int': the
                      conversion of any arbitrary (object) pointer to `char*' is
                      well-defined, but even so this does not justify the subsequent
                      attempt to convert a non-`int*' to an `int*'. There are a few
                      cases is which this is guaranteed to work (e.g., if `v' is a
                      struct whose first element is an `int'), but in general the
                      conversion is not safe.

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

                      Comment

                      • Lawrence Kirby

                        #12
                        Re: Where do pointers point to?

                        On Wed, 12 Jan 2005 01:41:37 +0000, Christian Bau wrote:
                        [color=blue]
                        > In article <cs1rtm$1irl$1@ mamut.aster.pl> ,
                        > "x-pander" <ngclc@pitek.eu .org> wrote:
                        >[color=green]
                        >> Is is guaranteed, that a pointer to any object in C points exactly at the
                        >> lowest addressed byte of this object?
                        >>
                        >> Specifcally is it possible for any platform/os/compiler combination that:
                        >> (char *)v != (void *)v
                        >> where v is an int variable for example.[/color]
                        >
                        > A pointer points to the whole object.[/color]

                        Right. An example is a an implementation on a word addressed architecture.
                        Let's say int corresponds to the word size. A pointer to an int will point
                        to the whole word on that architecture, it is incapable of pointing at a
                        single byte. Additionally the implementation chooses to support bytes
                        smaller than words by generating extra code to select the appropriate bits
                        from the word. A character pointer therefore needs more information (i.e.
                        which "byte" within the word to select) and will typically be larger than
                        a word pointer, and a conversion between the two types of pointer will
                        require a change of representation.
                        [color=blue]
                        > If you cast a pointer to another type, lets say from double* to int*,
                        > you get a pointer to an object that starts at the same place as the
                        > first object.[/color]

                        That is likely but is not guaranteed. Taking the example above converting
                        a char * to an int * can't achieve this if the character pointer doesn't
                        point at a word boundary.
                        [color=blue]
                        > So if you cast a pointer to char*, it points to the first
                        > byte of the object.[/color]

                        The standard has a specific rule that guarantees this when you convert to
                        pointers to character types, it isn't an example of a more general rule.
                        [color=blue]
                        > You cannot compare char* and void*. In your example, the compiler will
                        > convert the (void *) v automatically to char*, so you are actually
                        > comparing[/color]

                        The char * operand is converted to void *. It doesn't matter here but
                        is important for types other than pointers to characters.
                        [color=blue]
                        > (char *)v == (char *) (void *) v
                        >
                        > which is guaranteed to be equal.[/color]

                        Yes, void * uses the same representation as pointers to character types.

                        Lawrence

                        Comment

                        • Chris Croughton

                          #13
                          Re: Where do pointers point to?

                          On Tue, 11 Jan 2005 22:27:34 -0500, Eric Sosman
                          <esosman@acm-dot-org.invalid> wrote:
                          [color=blue]
                          > x-pander wrote:[color=green]
                          >>
                          >> So how about the result of the following comparision,
                          >> which i think has a potential of effectively answering my original question:
                          >>
                          >> (int *)(char *)&v != &v[/color]
                          >
                          > Guaranteed to work (evaluating to 0) if `v' is an `int'.
                          >
                          > Potential undefined behavior if `v' is not an `int': the
                          > conversion of any arbitrary (object) pointer to `char*' is
                          > well-defined, but even so this does not justify the subsequent
                          > attempt to convert a non-`int*' to an `int*'. There are a few
                          > cases is which this is guaranteed to work (e.g., if `v' is a
                          > struct whose first element is an `int'), but in general the
                          > conversion is not safe.[/color]

                          Am I correct in thinking that conversion of a T* to a char* is always
                          safe (because sizeof char <= sizeof T for all types T) but the other way
                          round may not be? For instance, an int* might be constrained to have
                          some bits zero, so conversion to an int* with those bits set might
                          either cause a hardware exception or 'silently' set the bits to zero.

                          Chris C

                          Comment

                          • S.Tobias

                            #14
                            Re: Where do pointers point to?

                            Christian Bau <christian.bau@ cbau.freeserve. co.uk> wrote:[color=blue]
                            > In article <cs1rtm$1irl$1@ mamut.aster.pl> ,
                            > "x-pander" <ngclc@pitek.eu .org> wrote:[/color]
                            [color=blue][color=green]
                            > > Is is guaranteed, that a pointer to any object in C points exactly at the
                            > > lowest addressed byte of this object?[/color][/color]

                            I'd say it's impossible to tell, unless you convert your pointer
                            to (char*), but then you're comparing different kind of pointers.
                            [color=blue][color=green]
                            > > Specifcally is it possible for any platform/os/compiler combination that:
                            > > (char *)v != (void *)v
                            > > where v is an int variable for example.[/color][/color]
                            [color=blue]
                            > A pointer points to the whole object.[/color]
                            [color=blue]
                            > If you cast a pointer to another type, lets say from double* to int*,
                            > you get a pointer to an object that starts at the same place as the
                            > first object. So if you cast a pointer to char*, it points to the first
                            > byte of the object.[/color]
                            [color=blue]
                            > You cannot compare char* and void*. In your example, the compiler will
                            > convert the (void *) v automatically to char*, so you are actually
                            > comparing[/color]

                            No, (char*)v will be implicitly converted to (void*) (cf. 6.5.9#5)
                            and void* pointers will be compared (although I can't see what possible
                            difference it might make which way we do the conversion - later, the
                            equality semantics doesn't depend on pointer type at all).
                            [color=blue]
                            > (char *)v == (char *) (void *) v[/color]
                            [color=blue]
                            > which is guaranteed to be equal.[/color]

                            int v;
                            (void*)(char*)& v == (void*)&v;

                            I still don't see it (maybe it's obvious, but it's still early morning
                            for me and a coffee didn't help). The Standard int 6.3.2.3 (Conversions ...
                            Pointers) only demands that (subject to alignment) conversions between
                            pointer types are reversible. However I don't see how you can infer
                            from it that single int*->void* conversion must yield the same value
                            as double conversion int*->char*->void*. How do you do it?

                            Where exactly is it written that the result of pointer conversion
                            (provided it doesn't invoke UB) must point to the same location
                            as the original pointer?

                            --
                            Stan Tobias
                            mailx `echo siXtY@FamOuS.Be dBuG.pAlS.INVALID | sed s/[[:upper:]]//g`

                            Comment

                            • Michael Mair

                              #15
                              Re: Where do pointers point to?

                              Lawrence Kirby wrote:

                              [snip: void * vs char *]
                              [color=blue]
                              > Yes, void * uses the same representation as pointers to character types.[/color]

                              Are you sure of that? It is IMO logical but not necessary.

                              I am not sure where but a couple of months ago there was a
                              discussion where the example function execl() from the FAQ 5.2
                              ( http://www.eskimo.com/~scs/C-faq/q5.2.html ) was cited and
                              where some regulars stressed how important the cast (char *)
                              is because execl is a function with variable argument list
                              and so we need to make sure that we get (char *) NULL instead
                              of plain (that is, (void *)) NULL.


                              Cheers
                              Michael
                              --
                              E-Mail: Mine is an /at/ gmx /dot/ de address.

                              Comment

                              Working...