casting from int to void* and back to int

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

    #1

    casting from int to void* and back to int

    Hi All,

    I apologize if this has been brought up here before.
    Searching through the newsgroup I found variants of
    my question, but not exactly what I am thinking about.

    If on a given platform, I am guaranteed that:
    sizeof(integer) <= sizeof(void*)
    Is it safe to store an int in a void* and cast it
    back to int without truncating/losing data ?

    Secondly, is the minimum size of a void* (or char*),
    defined in the standards or is it entirely platform
    dependant ?

    TIA,
    Pranab
  • Jeremy Yallop

    #2
    Re: casting from int to void* and back to int

    Pranab Mehta wrote:[color=blue]
    > If on a given platform, I am guaranteed that:
    > sizeof(integer) <= sizeof(void*)
    > Is it safe to store an int in a void* and cast it
    > back to int without truncating/losing data ?[/color]

    It's not safe, in that there's no guarantee in the standard that it
    will work. C99 defines the types "intptr_t" and "uintptr_t" which do
    preserve equality on round-trip conversions with pointer to void, but
    unfortunately the trip is the wrong way: void* -> integer -> void*
    rather than integer -> void* -> integer.

    If int is no larger than pointer to void then one way to store the
    value is by simply copying the bytes:

    int i = value;
    void *p;
    memcpy(&p, &i, sizeof i);

    If you later copy the bytes back into an int object, the value is
    guaranteed to be the same as the original. This method has the
    (rather major) drawback that you can't use the pointer to void as a
    value, even the trivial expression statement

    p;

    invokes undefined behaviour if the representation is not a valid one
    for pointer to void. This means that it's also not strictly safe to
    pass the pointer to void to functions, for example.

    Storing an int in a pointer to void is a pretty nasty thing to do, and
    indicates a possible problem with your design, in my opinion.
    [color=blue]
    > Secondly, is the minimum size of a void* (or char*),
    > defined in the standards or is it entirely platform
    > dependant ?[/color]

    In a C99 hosted environment a pointer to void must be at least 17 bits
    wide.

    Jeremy.

    Comment

    • Eric Sosman

      #3
      Re: casting from int to void* and back to int

      Pranab Mehta wrote:[color=blue]
      >
      > Hi All,
      >
      > I apologize if this has been brought up here before.
      > Searching through the newsgroup I found variants of
      > my question, but not exactly what I am thinking about.
      >
      > If on a given platform, I am guaranteed that:
      > sizeof(integer) <= sizeof(void*)
      > Is it safe to store an int in a void* and cast it
      > back to int without truncating/losing data ?[/color]

      Is it "safe?" Yes, because on the great majority of
      C implementations it will work as you desire. Is it
      "perfectly safe?" No, because the C language Standard
      does not specify the result of either conversion, and it
      is therefore possible that some C implementation might
      not give the desired result.

      You must make your own decisions about how much "safety"
      your applicaition requires.
      [color=blue]
      > Secondly, is the minimum size of a void* (or char*),
      > defined in the standards or is it entirely platform
      > dependant ?[/color]

      I'm not sure what you are asking here. No C object
      can have a `sizeof' smaller than 1. No non-aggregate
      object is required to have a `sizeof' greater than 1.
      All the Standard has to say about your question is

      1 <= sizeof(void*) && sizeof(void*) == sizeof(char*)

      .... and each implementation is free to choose any value
      satisfying these constratints.

      --
      Eric.Sosman@sun .com

      Comment

      • Leor Zolman

        #4
        Re: casting from int to void* and back to int

        On 12 Apr 2004 13:32:48 -0700, pranab@employee s.org (Pranab Mehta) wrote:
        [color=blue]
        >Hi All,
        >
        >I apologize if this has been brought up here before.
        >Searching through the newsgroup I found variants of
        >my question, but not exactly what I am thinking about.
        >
        >If on a given platform, I am guaranteed that:
        > sizeof(integer) <= sizeof(void*)
        >Is it safe to store an int in a void* and cast it
        >back to int without truncating/losing data ?
        >[/color]

        I was hesitant to be the first one to attempt to answer this, and I'm glad
        I waited ;-)
        In any case, Jeremy brought up the thing that immediately popped into my
        mind upon first reading your post: "Why?"
        As much as I wrinkle up my nose at the thought of using unions, in this
        particular case my nose curls even higher at the thought of the cast you
        proposed (and my ears begin to wiggle). Could the use of a union possibly
        spare you from the indignity of such an ugly cast?
        -leor

        --
        Leor Zolman --- BD Software --- www.bdsoft.com
        On-Site Training in C/C++, Java, Perl and Unix
        C++ users: Download BD Software's free STL Error Message Decryptor at:
        An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

        Comment

        • jacob navia

          #5
          Re: casting from int to void* and back to int

          In a 64 bit machine with sizeof(int) == 4
          and sizeof(void *) == 8 this will fail.

          Such a system is the new 64 bit version of
          windows for instance.

          For that system, lcc-win32 uses:
          sizeof(int) == sizeof(long) == 4
          sizeof(void *) == sizeof(long long) == 8

          You should never assume that an int will hold
          a pointer since windows 2.0...

          In the 16 bit world we had
          sizeof(int) == sizeof(short) == 2
          sizeof(char *) ==sizeof(long) == 4

          using the FAR memory model. Using the SMALL/NEAR
          memory model you had
          sizeof(int) == sizeof(void *) == 2

          Mixtures of pointers were possible, with
          data pointers in 32 bits and code pointers
          in 16 bits, etc.

          Windows 32 introduced
          sizeof(int) == 4 == sizeof(void *).

          Since 1995, you can store a pointer
          in an integer. This will not work in
          64 bit windows systems where a void *
          is 8.

          If the expected life time
          of your software will not exceed a few
          years, you can still do it since 64 bit
          systems will run 32 bit software using
          an emulation layer.

          jacob

          http://www.cs.virginia.edu/~lcc-win32


          Comment

          • Eric Sosman

            #6
            Re: casting from int to void* and back to int

            jacob navia wrote:[color=blue]
            >
            > In a 64 bit machine with sizeof(int) == 4
            > and sizeof(void *) == 8 this will fail.
            >
            > Such a system is the new 64 bit version of
            > windows for instance.
            >
            > For that system, lcc-win32 uses:
            > sizeof(int) == sizeof(long) == 4
            > sizeof(void *) == sizeof(long long) == 8
            >
            > You should never assume that an int will hold
            > a pointer since windows 2.0...
            > [...][/color]

            He's attempting int -> void* -> int, not
            void* -> int -> void*.

            --
            Eric.Sosman@sun .com

            Comment

            • CBFalconer

              #7
              Re: casting from int to void* and back to int

              Jeremy Yallop wrote:[color=blue]
              >[/color]
              .... snip ...[color=blue]
              >
              > In a C99 hosted environment a pointer to void must be at least
              > 17 bits wide.[/color]

              Where did you get this? Chapter & verse please.

              --
              fix (vb.): 1. to paper over, obscure, hide from public view; 2.
              to work around, in a way that produces unintended consequences
              that are worse than the original problem. Usage: "Windows ME
              fixes many of the shortcomings of Windows 98 SE". - Hutchison

              Comment

              • Jeremy Yallop

                #8
                Re: casting from int to void* and back to int

                CBFalconer wrote:[color=blue]
                > Jeremy Yallop wrote:[color=green]
                >>[/color]
                > ... snip ...[color=green]
                >>
                >> In a C99 hosted environment a pointer to void must be at least
                >> 17 bits wide.[/color]
                >
                > Where did you get this? Chapter & verse please.[/color]

                5.2.4.1 Translation limits

                1 The implementation shall be able to translate and execute at
                least one program tha\t contains at least one instance of every
                one of the following limits:
                [...]

                -- 65535 bytes in an object (in a hosted environment only)

                A pointer to void must be able to represent the address of every byte
                of such an object, plus a null pointer, plus one past the end of the
                object, and perhaps one or two other things. To represent 65537
                distinct values requires 17 bits of storage.

                Jeremy.

                Comment

                • jacob navia

                  #9
                  Re: casting from int to void* and back to int


                  "Eric Sosman" <Eric.Sosman@su n.com> a écrit dans le message de
                  news:407B137D.D CAF5271@sun.com ...[color=blue]
                  > jacob navia wrote:
                  >
                  > He's attempting int -> void* -> int, not
                  > void* -> int -> void*.
                  >
                  > --
                  > Eric.Sosman@sun .com[/color]

                  Read the original message please:[color=blue]
                  > Is it safe to store an int in a void* and cast it
                  > back to int without truncating/losing data ?[/color]



                  Comment

                  • Irrwahn Grausewitz

                    #10
                    Re: casting from int to void* and back to int

                    "jacob navia" <jacob@jacob.re mcomp.fr> wrote:[color=blue]
                    >
                    >"Eric Sosman" <Eric.Sosman@su n.com> a écrit dans le message de
                    >news:407B137D. DCAF5271@sun.co m...[color=green]
                    >> jacob navia wrote:
                    >>
                    >> He's attempting int -> void* -> int, not
                    >> void* -> int -> void*.
                    >>
                    >> --
                    >> Eric.Sosman@sun .com[/color]
                    >
                    >Read the original message please:[color=green]
                    >> Is it safe to store an int in a void* and cast it
                    >> back to int without truncating/losing data ?[/color][/color]

                    He obviously already did; but did you?
                    --
                    Irrwahn Grausewitz (irrwahn33@free net.de)
                    welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
                    clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
                    clc OT guide : http://benpfaff.org/writings/clc/off-topic.html

                    Comment

                    • CBFalconer

                      #11
                      Re: casting from int to void* and back to int

                      Jeremy Yallop wrote:[color=blue]
                      > CBFalconer wrote:[color=green]
                      >> Jeremy Yallop wrote:[color=darkred]
                      >>>[/color]
                      >> ... snip ...[color=darkred]
                      >>>
                      >>> In a C99 hosted environment a pointer to void must be at least
                      >>> 17 bits wide.[/color]
                      >>
                      >> Where did you get this? Chapter & verse please.[/color]
                      >
                      > 5.2.4.1 Translation limits
                      >
                      > 1 The implementation shall be able to translate and execute at
                      > least one program tha\t contains at least one instance of
                      > every one of the following limits:
                      > [...]
                      >
                      > -- 65535 bytes in an object (in a hosted environment only)
                      >
                      > A pointer to void must be able to represent the address of every
                      > byte of such an object, plus a null pointer, plus one past the
                      > end of the object, and perhaps one or two other things. To
                      > represent 65537 distinct values requires 17 bits of storage.[/color]

                      Consider that a pointer need not consist of a single address. It
                      may very well be an index into a table, for example. Pointers to
                      all those objects need not exist simultaneously. If they did they
                      would use up all that minimum storage specified.

                      --
                      fix (vb.): 1. to paper over, obscure, hide from public view; 2.
                      to work around, in a way that produces unintended consequences
                      that are worse than the original problem. Usage: "Windows ME
                      fixes many of the shortcomings of Windows 98 SE". - Hutchison

                      Comment

                      • jacob navia

                        #12
                        Re: casting from int to void* and back to int

                        BOTH ways are non portable.
                        int -->void * -->int
                        or
                        void *-->int-->void *


                        Comment

                        • Irrwahn Grausewitz

                          #13
                          Re: casting from int to void* and back to int

                          "jacob navia" <jacob@jacob.re mcomp.fr> wrote:[color=blue]
                          >BOTH ways are non portable.
                          >int -->void * -->int
                          >or
                          >void *-->int-->void *[/color]

                          To whom or what are you replying?
                          --
                          Irrwahn Grausewitz (irrwahn33@free net.de)
                          welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
                          clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
                          clc OT guide : http://benpfaff.org/writings/clc/off-topic.html

                          Comment

                          • jacob navia

                            #14
                            Re: casting from int to void* and back to int


                            "Eric Sosman" <Eric.Sosman@su n.com> a écrit dans le message de
                            news:407B137D.D CAF5271@sun.com ...[color=blue]
                            > jacob navia wrote:
                            >
                            > He's attempting int -> void* -> int, not
                            > void* -> int -> void*.
                            >[/color]

                            Ahhh. You think that the result would be different???


                            Comment

                            • Eric Sosman

                              #15
                              Re: casting from int to void* and back to int

                              jacob navia wrote:[color=blue]
                              >
                              > "Eric Sosman" <Eric.Sosman@su n.com> a écrit dans le message de
                              > news:407B137D.D CAF5271@sun.com ...[color=green]
                              > > jacob navia wrote:
                              > >
                              > > He's attempting int -> void* -> int, not
                              > > void* -> int -> void*.
                              > >[/color]
                              >
                              > Ahhh. You think that the result would be different???[/color]

                              Under the conditions specified by the O.P.:
                              [color=blue]
                              > If on a given platform, I am guaranteed that:
                              > sizeof(integer) <= sizeof(void*)[/color]

                              ... it is "likely" that the result will be as desired,
                              that is, that the original int value will survive being
                              converted to void* and back. As others (you among them)
                              have pointed out, "likely" is not "certain" because the
                              Standard makes no such guarantee.

                              Converting an arbitrary pointer value to an `int'
                              and back is "less likely" to work, for the reasons you
                              listed in your first post to this (interminable) thread.

                              --
                              Eric.Sosman@sun .com

                              Comment

                              Working...