size of pointers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • subramanian100in@yahoo.com, India

    size of pointers

    Given that the sizes of pointers to different data types(built-in or
    structures) can be different, though malloc returns a void *, it is
    assigned to any pointer type. The language allows it. From this, can I
    conclude that the size of (void *) should be the maximum ?

    If this is not the case, consider the following scenario.
    Suppose there is a type T (built-in or structure) whose pointer size
    is bigger than the sizeof (void *) ie sizeof (T *) sizeof(void *).

    Consider;
    T *var;
    var = malloc(sizeof(T ));

    Then how can the pointer returned by malloc(which would be a void *)
    for the sizeof type T be assigned to a variabe of type T.


    Thanks

  • subramanian100in@yahoo.com, India

    #2
    Re: size of pointers

    On Mar 12, 12:49 pm, "subramanian10. ..@yahoo.com, India"
    <subramanian10. ..@yahoo.comwro te:
    Given that the sizes of pointers to different data types(built-in or
    structures) can be different, though malloc returns a void *, it is
    assigned to any pointer type. The language allows it. From this, can I
    conclude that the size of (void *) should be the maximum ?
    >
    If this is not the case, consider the following scenario.
    Suppose there is a type T (built-in or structure) whose pointer size
    is bigger than the sizeof (void *) ie sizeof (T *) sizeof(void *).
    >
    Consider;
    T *var;
    var = malloc(sizeof(T ));
    >
    Then how can the pointer returned by malloc(which would be a void *)
    for the sizeof type T be assigned to a variabe of type T.
    >
    Thanks
    I was wrong. Can we conclude that sizeof (void *) should be the
    minimum ?

    Thanks

    Comment

    • santosh

      #3
      Re: size of pointers

      subramanian100i n@yahoo.com, India wrote:
      On Mar 12, 12:49 pm, "subramanian10. ..@yahoo.com, India"
      <subramanian10. ..@yahoo.comwro te:
      Given that the sizes of pointers to different data types(built-in or
      structures) can be different, though malloc returns a void *, it is
      assigned to any pointer type. The language allows it. From this, can I
      conclude that the size of (void *) should be the maximum ?

      If this is not the case, consider the following scenario.
      Suppose there is a type T (built-in or structure) whose pointer size
      is bigger than the sizeof (void *) ie sizeof (T *) sizeof(void *).

      Consider;
      T *var;
      var = malloc(sizeof(T ));

      Then how can the pointer returned by malloc(which would be a void *)
      for the sizeof type T be assigned to a variabe of type T.

      Thanks
      >
      I was wrong. Can we conclude that sizeof (void *) should be the
      minimum ?
      The size need not be connected to representation. A pointer of type
      void should have the same representation and alignment requirements as
      a pointer to char. It should also be convertible to any other object
      or incomplete type and back again without loss of functionality. All
      this implies that pointers of type void must have a representation and
      alignment requirements that are the most general and least strict.
      Whether that translates directly to the relative sizes of pointer
      types is not directly specified by the Standard.

      Comment

      • santosh

        #4
        Re: size of pointers

        santosh wrote:
        subramanian100i n@yahoo.com, India wrote:
        On Mar 12, 12:49 pm, "subramanian10. ..@yahoo.com, India"
        <subramanian10. ..@yahoo.comwro te:
        Given that the sizes of pointers to different data types(built-in or
        structures) can be different, though malloc returns a void *, it is
        assigned to any pointer type. The language allows it. From this, can I
        conclude that the size of (void *) should be the maximum ?
        >
        If this is not the case, consider the following scenario.
        Suppose there is a type T (built-in or structure) whose pointer size
        is bigger than the sizeof (void *) ie sizeof (T *) sizeof(void *).
        >
        Consider;
        T *var;
        var = malloc(sizeof(T ));
        >
        Then how can the pointer returned by malloc(which would be a void *)
        for the sizeof type T be assigned to a variabe of type T.
        >
        Thanks
        I was wrong. Can we conclude that sizeof (void *) should be the
        minimum ?
        >
        The size need not be connected to representation. A pointer of type
        void should have the same representation and alignment requirements as
        a pointer to char. It should also be convertible to any other object
        or incomplete type and back again without loss of functionality.
        The last sentence in the paragraph above should read:

        It should also be convertible to a pointer to any other object or
        incomplete type and back again, without loss of functionality or
        representation.

        Comment

        • Flash Gordon

          #5
          Re: size of pointers

          subramanian100i n@yahoo.com, India wrote, On 12/03/07 07:49:
          Given that the sizes of pointers to different data types(built-in or
          structures) can be different, though malloc returns a void *, it is
          assigned to any pointer type. The language allows it. From this, can I
          conclude that the size of (void *) should be the maximum ?
          It is probably true but not guaranteed.
          If this is not the case, consider the following scenario.
          Suppose there is a type T (built-in or structure) whose pointer size
          is bigger than the sizeof (void *) ie sizeof (T *) sizeof(void *).
          >
          Consider;
          T *var;
          var = malloc(sizeof(T ));
          >
          Then how can the pointer returned by malloc(which would be a void *)
          for the sizeof type T be assigned to a variabe of type T.
          It can be done because the compiler is required to do whatever
          conversion is required. Note that there might actually be some change
          rather than simply copying the bits!
          --
          Flash Gordon

          Comment

          • Keith Thompson

            #6
            Re: size of pointers

            "subramanian100 in@yahoo.com, India" <subramanian100 in@yahoo.comwri tes:
            Given that the sizes of pointers to different data types(built-in or
            structures) can be different, though malloc returns a void *, it is
            assigned to any pointer type. The language allows it. From this, can I
            conclude that the size of (void *) should be the maximum ?
            [...]

            The standard guarantees that you can convert a pointer to any object
            or incomplete type to void* and back again without loss of
            information. The most obvious way for an implementation to satisfy
            this requirement is to make void* at least as big as any other pointer
            to object or incomplete type, but the standard doesn't require this,
            or even suggest it. For example, a pointer might contain bits that
            don't contribute to the value of the pointer (similar to "padding
            bits", but the standard uses that term only for integer types). Or
            the effective value of a pointer might depend on information not
            stored in the pointer itself; for example, a pointer might be, or
            might contain, an index into some system-wide table with additional
            information.

            In most implementations (at least, most of the ones I'm familiar
            with), all pointers have the same size and representation, and all
            pointer conversions just copy the bits. (Remember, again, that the
            standard does not require or suggest this.)

            The next most common scheme is probably one where a machine address
            points to a "word", some unit of memory bigger than a byte. A void*
            or char* pointer then needs to hold additional information to specify
            which part of the word it refers to. In the one implementation like
            this that I've actually used, there was enough room in the high-order
            bits to store the offset. In other implementations , char* and void*
            pointers might be bigger than, say, int* or double*, and conversions
            might be non-trivial.

            Stranger schemes are possible, and the standard goes to some lengths
            *not* to be so specific that it would exclude some possibilities.

            Finally, function pointers can be completely unrelated to object
            pointers; the language doesn't even specify a conversion between
            function pointers and void*. I think that the IBM AS/400 architecture
            has function pointers that are substantially larger than object
            pointers, and probably larger than void*.

            I've ignored issues regarding segmented memory, and so-called "near"
            and "far" pointers, mostly because I've never used them.

            --
            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."
            -- Antony Jay and Jonathan Lynn, "Yes Minister"

            Comment

            • Chris Torek

              #7
              Re: size of pointers

              >"subramanian10 0in@yahoo.com, India" <subramanian100 in@yahoo.comwri tes:
              >Given that the sizes of pointers to different data types(built-in or
              >structures) can be different, though malloc returns a void *, it is
              >assigned to any pointer type. The language allows it. From this, can I
              >conclude that the size of (void *) should be the maximum ?
              In article <ln3b4affe4.fsf @nuthaus.mib.or g>
              Keith Thompson <kst-u@mib.orgwrote:

              [a bunch of correct stuff, mostly elided; keeping just these bits to
              comment upon:]
              >The next most common scheme is probably one where a machine address
              >points to a "word", some unit of memory bigger than a byte. A void*
              >or char* pointer then needs to hold additional information to specify
              >which part of the word it refers to. In the one implementation like
              >this that I've actually used, there was enough room in the high-order
              >bits to store the offset. In other implementations , char* and void*
              >pointers might be bigger than, say, int* or double*, and conversions
              >might be non-trivial.
              These did exist in the past, and might again. The early PR1ME systems
              were one example where "char *" was 48 bits, while "int *" was just
              32. (These systems predated "void *".)
              >Stranger schemes are possible, and the standard goes to some lengths
              >*not* to be so specific that it would exclude some possibilities.
              Indeed. What this all boils down to, for data pointers anyway
              ("data pointers" meaning everything excluding "pointer to
              function", as Keith Thompson notes in a paragraph I removed),
              is ... well:

              typedef /* insert data type here */ *PT;

              if (sizeof(PT) sizeof(void *))
              puts("this should never happen");

              *should* never print any output on any "sensible" system, which
              is what subramanian100i n suggested -- but the C standards (C89
              and C99 both) do not require systems to be "sensible".
              --
              In-Real-Life: Chris Torek, Wind River Systems
              Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
              email: forget about it http://web.torek.net/torek/index.html
              Reading email is like searching for food in the garbage, thanks to spammers.

              Comment

              • subramanian100in@yahoo.com, India

                #8
                Re: size of pointers

                On Mar 14, 12:51 pm, Chris Torek <nos...@torek.n etwrote:
                "subramanian10. ..@yahoo.com, India" <subramanian10. ..@yahoo.comwri tes:
                Given that the sizes of pointers to different data types(built-in or
                structures) can be different, though malloc returns a void *, it is
                assigned to any pointer type. The language allows it. From this, can I
                conclude that the size of (void *) should be the maximum ?
                >
                In article <ln3b4affe4.... @nuthaus.mib.or g>
                Keith Thompson <k...@mib.orgwr ote:
                >
                [a bunch of correct stuff, mostly elided; keeping just these bits to
                comment upon:]
                >
                The next most common scheme is probably one where a machine address
                points to a "word", some unit of memory bigger than a byte. A void*
                or char* pointer then needs to hold additional information to specify
                which part of the word it refers to. In the one implementation like
                this that I've actually used, there was enough room in the high-order
                bits to store the offset. In other implementations , char* and void*
                pointers might be bigger than, say, int* or double*, and conversions
                might be non-trivial.
                >
                These did exist in the past, and might again. The early PR1ME systems
                were one example where "char *" was 48 bits, while "int *" was just
                32. (These systems predated "void *".)
                >
                Stranger schemes are possible, and the standard goes to some lengths
                *not* to be so specific that it would exclude some possibilities.
                >
                Indeed. What this all boils down to, for data pointers anyway
                ("data pointers" meaning everything excluding "pointer to
                function", as Keith Thompson notes in a paragraph I removed),
                is ... well:
                >
                typedef /* insert data type here */ *PT;
                >
                if (sizeof(PT) sizeof(void *))
                puts("this should never happen");
                >
                *should* never print any output on any "sensible" system, which
                is what subramanian100i n suggested -- but the C standards (C89
                and C99 both) do not require systems to be "sensible".
                --
                I am a beginner. So please bear with me. Can I request someone to
                clarify the following doubt as well.

                Consdier "void *" and qsort() library function are allowed in an
                implementation.

                To the library function qsort(), we pass the base as "void *". So one
                conversion to "void *" happens here.
                When the user-defined comparison function is called back by the
                qsort() library, it passes two "const void *" arguments. These two
                arguments will be cast to some types in the comparison function to
                make a comparison and return an integer value. So here, conversion
                from "const void *" to appropriate pointer type happens.

                Now my question is, shouldn't all pointers be of the same size ?
                (I learned that they need not be) But still, just to get clarified, I
                have written this question. Kindly reply

                Thanks

                Comment

                • Flash Gordon

                  #9
                  Re: size of pointers

                  subramanian100i n@yahoo.com, India wrote, On 14/03/07 11:41:
                  On Mar 14, 12:51 pm, Chris Torek <nos...@torek.n etwrote:
                  >>"subramanian1 0...@yahoo.com, India" <subramanian10. ..@yahoo.comwri tes:
                  >>>Given that the sizes of pointers to different data types(built-in or
                  >>>structures ) can be different, though malloc returns a void *, it is
                  >>>assigned to any pointer type. The language allows it. From this, can I
                  >>>conclude that the size of (void *) should be the maximum ?
                  >In article <ln3b4affe4.... @nuthaus.mib.or g>
                  >Keith Thompson <k...@mib.orgwr ote:
                  >>
                  >[a bunch of correct stuff, mostly elided; keeping just these bits to
                  >comment upon:]
                  >>
                  >>The next most common scheme is probably one where a machine address
                  >>points to a "word", some unit of memory bigger than a byte. A void*
                  >>or char* pointer then needs to hold additional information to specify
                  >>which part of the word it refers to. In the one implementation like
                  >>this that I've actually used, there was enough room in the high-order
                  >>bits to store the offset. In other implementations , char* and void*
                  >>pointers might be bigger than, say, int* or double*, and conversions
                  >>might be non-trivial.
                  >These did exist in the past, and might again. The early PR1ME systems
                  >were one example where "char *" was 48 bits, while "int *" was just
                  >32. (These systems predated "void *".)
                  >>
                  >>Stranger schemes are possible, and the standard goes to some lengths
                  >>*not* to be so specific that it would exclude some possibilities.
                  >Indeed. What this all boils down to, for data pointers anyway
                  >("data pointers" meaning everything excluding "pointer to
                  >function", as Keith Thompson notes in a paragraph I removed),
                  >is ... well:
                  >>
                  > typedef /* insert data type here */ *PT;
                  >>
                  > if (sizeof(PT) sizeof(void *))
                  > puts("this should never happen");
                  >>
                  >*should* never print any output on any "sensible" system, which
                  >is what subramanian100i n suggested -- but the C standards (C89
                  >and C99 both) do not require systems to be "sensible".
                  >--
                  >
                  I am a beginner. So please bear with me. Can I request someone to
                  clarify the following doubt as well.
                  >
                  Consdier "void *" and qsort() library function are allowed in an
                  implementation.
                  >
                  To the library function qsort(), we pass the base as "void *". So one
                  conversion to "void *" happens here.
                  When the user-defined comparison function is called back by the
                  qsort() library, it passes two "const void *" arguments. These two
                  arguments will be cast to some types in the comparison function to
                  make a comparison and return an integer value. So here, conversion
                  from "const void *" to appropriate pointer type happens.
                  A conversion has to be done, but it can be done without a cast, e.g.
                  const int *intptr = voidptr;

                  Note that a conversion involves doing whatever changes are required,
                  even if that is reverse the order of the bits.
                  Now my question is, shouldn't all pointers be of the same size ?
                  No, each should be the size required to do the job efficiently on the
                  system it is used on. If that means that each pointer type is a
                  different size then so be it.
                  (I learned that they need not be) But still, just to get clarified, I
                  have written this question. Kindly reply
                  As you have learned that they need not be then why do you think they
                  should be? Also, why do you think it matters? Occasionally one does
                  strange things, but it is pretty rare to actually need to care about the
                  size of pointer.
                  --
                  Flash Gordon

                  Comment

                  • Joe Wright

                    #10
                    Re: size of pointers

                    subramanian100i n@yahoo.com, India wrote:
                    >
                    [ much snippage ]
                    I am a beginner. So please bear with me. Can I request someone to
                    clarify the following doubt as well.
                    >
                    Consdier "void *" and qsort() library function are allowed in an
                    implementation.
                    >
                    To the library function qsort(), we pass the base as "void *". So one
                    conversion to "void *" happens here.
                    Well no. The prototype of qsort declares a void* as the first parameter.
                    We pass it the address of the array we want to sort.
                    When the user-defined comparison function is called back by the
                    qsort() library, it passes two "const void *" arguments. These two
                    arguments will be cast to some types in the comparison function to
                    make a comparison and return an integer value. So here, conversion
                    from "const void *" to appropriate pointer type happens.
                    >
                    Yes.
                    Now my question is, shouldn't all pointers be of the same size ?
                    (I learned that they need not be) But still, just to get clarified, I
                    have written this question. Kindly reply
                    They probably are on most machines. The notion of using shorter pointers
                    for larger objects was to save transistors in the CPU. This was a
                    hardware design thing, nothing to do with C. In the past several years
                    the cost of a transistor in CPU design has been reduced to (effectively)
                    0. I expect all pointer hardware to be the same size from now on.

                    --
                    Joe Wright
                    "Everything should be made as simple as possible, but not simpler."
                    --- Albert Einstein ---

                    Comment

                    • santosh

                      #11
                      Re: size of pointers

                      subramanian100i n@yahoo.com, India wrote:

                      <snip>
                      Now my question is, shouldn't all pointers be of the same size ?
                      (I learned that they need not be) But still, just to get clarified, I
                      have written this question. Kindly reply
                      The C Standard says nothing about the relative sizes of pointer types.
                      It says that each pointer should be able to point to objects of it's
                      type, and that void and char pointers should be able to point to any
                      type of object. It also says that conversion from T* to void*, (or
                      char *), and back again should result in no loss of representation and
                      function. It also says that pointers to structure types should be
                      similar, as should those for unions.

                      The implementation is free to choose whatever sizes it prefers for
                      different pointer types, as long as all the requirements mentioned in
                      the Standard are complied with.

                      Having said that, under most modern hardware, pointers tend to be of
                      uniform size.

                      Comment

                      • Chris Torek

                        #12
                        Re: size of pointers

                        In article <1173872516.073 686.199690@n59g 2000hsh.googleg roups.com>
                        subramanian100i n@yahoo.com, India <subramanian100 in@yahoo.comwro te:
                        >Consider "void *" and qsort() library function are allowed in an
                        >implementation .
                        >
                        >To the library function qsort(), we pass the base as "void *". So one
                        >conversion to "void *" happens here.
                        Right.
                        >When the user-defined comparison function is called back by the
                        >qsort() library, it passes two "const void *" arguments.
                        Yes; these will point to the first (where "first" is a little bit
                        vague) bytes of the two objects-in-memory that are to be compared.
                        >These two arguments will be cast to some types in the comparison
                        >function to make a comparison and return an integer value.
                        "Cast" in C refers specifically to the syntax using a type-name
                        in parentheses:

                        (int)3.1415926

                        for instance. The two arguments need only be converted, not necessarily
                        cast.
                        >So here, conversion from "const void *" to appropriate pointer type
                        >happens.
                        Right.
                        >Now my question is, shouldn't all pointers be of the same size?
                        They need not be.

                        Suppose that, for some reason, "void *" is stored in a one-megabyte
                        region, while other pointers are stored in a mere four or eight bytes.
                        Suppose further that our implementation uses four bytes.

                        Clearly, we can take any valid four-byte entity and stuff all four
                        bytes into the one-megabyte region provided by a "void *". The
                        remaining 1048572 (1 million minus 4) bytes can be set to any other
                        value (perhaps zero) or even just left alone.

                        So:

                        int *ip = &some_intege r;
                        void *vp;
                        ...
                        vp = ip;

                        takes the four-byte value that points to "some_integ er" and puts
                        those four bytes into 4 of the 1048576 bytes in "vp". (They fit
                        just fine, obviously.)

                        Later, we do something like this:

                        int *new_ip;
                        ...
                        new_ip = vp;

                        This reaches somewhere into those 1048576 bytes and pulls out four
                        of them. It assumes those four are the "right" four that will
                        point to an integer somewhere -- in our case, "some_integ er".
                        If we have done our part, the C implementation will do its part,
                        and doing "*new_ip = 42" will set "some_integ er" to 42.

                        More practically, consider those older machines, where "char *"
                        needs 48 or 64 bits. On these machines, a "machine address" gives
                        you the number of a "machine word" in memory. If the machine has
                        32-bit words, and has 2^32 of them (i.e., 4 gigawords of RAM, which
                        is 16 gigabytes), then every possible word address is valid. In
                        order to pick out one particular byte within a four-byte word,
                        "char *" needs to store *two* things:

                        - the 32 bit address of the word, and
                        - two more bits to select which of the four bytes we want,
                        within that word.

                        That is:

                        int x;
                        char *p;

                        p = (char *)&x;

                        If "x" is at machine address 0x12345678, this sets "p" to
                        <0x12345678,0 >, which means "byte #0 in the word at 0x12345678".
                        Then:

                        p++;

                        increments the byte-offset in p, changing the value from <0x12345678,0 >
                        to <0x12345678,1 >. Incrementing p several more times gives
                        <0x12345678,2 >, then <0x12345678,3 >, and finally <0x12345679,0 >.
                        In other words, pointer arithmetic on "sub-words" manipulates the
                        byte offset, and only when that "overflows" , the word address.

                        If you use an "int *", on the other hand, it only needs to hold
                        a regular machine word address, i.e., a 32-bit value. So "int *"
                        here is smaller than "char *".

                        Since "void *" needs to hold any value, it has to have the same
                        "extra bits" as "char *". When you convert some "original" pointer
                        to "void *", the compiler copies the word address unchanged. If
                        the original pointer has a byte offset, the compiler copies that
                        too, otherwise it sets the byte offset to 0. When you convert a
                        "saved" address from "void *" to some other type, the compiler
                        copies the word address, and copies the byte offset only if the
                        new pointer has one -- otherwise it just throws it away (or perhaps
                        produces a runtime fault if the byte offset is not zero).

                        The C standards promise only that if you -- the programmer -- are
                        careful about pulling out of a "void *" that which you put into
                        the "void *" earlier, you will get something sensible. If you
                        mix things up, you may not.
                        --
                        In-Real-Life: Chris Torek, Wind River Systems
                        Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
                        email: forget about it http://web.torek.net/torek/index.html
                        Reading email is like searching for food in the garbage, thanks to spammers.

                        Comment

                        Working...