Portable typecast

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

    #1

    Portable typecast

    Hi,

    I have a piece of code which looks like the following:

    void f2(int i)
    {

    }

    void f1(HANDLE h, const void *pSetting1, const void *pSetting2)
    {
    switch(...)
    {
    case ABC:
    f2((int) pSetting1);
    }
    }

    Assuming f1 takes a void pointer (actually two of them but it doesn't
    matter) I need to call f2 where I know that the variable really holds an
    integer.
    Due to compatibility with C the function f1 needs to be with C declaration
    and for this reason I cannot use function overloading with different
    parameters depending on the input type. Therefore it's assumed that f1() can
    take input of various types such as integers or pointers of specific types.
    In the example above I want to cast the void pointer to an integer but this
    fails on 64 bit platforms due to the fact that it goes from 64 bit to 32.
    On platforms with gcc I've previously used constructs like (int) (unsigned
    long) since unsigned long is 64 bit wide on those platforms. However this
    could cause problems with Win64 since Microsoft uses another 64 bit model
    then commonly used under unix.
    How would I cast this in platform independent way to ensure that the result
    would be as expected on both 32 and 64 bit platforms?

    Thanks.

    -- Henrik


  • amparikh@gmail.com

    #2
    Re: Portable typecast


    Henrik Goldman wrote:
    Hi,
    >
    I have a piece of code which looks like the following:
    >
    void f2(int i)
    {
    >
    }
    >
    void f1(HANDLE h, const void *pSetting1, const void *pSetting2)
    {
    switch(...)
    {
    case ABC:
    f2((int) pSetting1);
    }
    }
    >
    Assuming f1 takes a void pointer (actually two of them but it doesn't
    matter) I need to call f2 where I know that the variable really holds an
    integer.
    Due to compatibility with C the function f1 needs to be with C declaration
    and for this reason I cannot use function overloading with different
    parameters depending on the input type. Therefore it's assumed that f1() can
    take input of various types such as integers or pointers of specific types.
    In the example above I want to cast the void pointer to an integer but this
    fails on 64 bit platforms due to the fact that it goes from 64 bit to 32.
    On platforms with gcc I've previously used constructs like (int) (unsigned
    long) since unsigned long is 64 bit wide on those platforms. However this
    could cause problems with Win64 since Microsoft uses another 64 bit model
    then commonly used under unix.
    How would I cast this in platform independent way to ensure that the result
    would be as expected on both 32 and 64 bit platforms?
    >
    Thanks.
    >
    -- Henrik
    You probably need to post this question on the Microsoft win32
    newsgroup. You might find answers there. or else just search for
    ULONG_PTR in there. I am sure you would get the answer.

    Comment

    • Ondra Holub

      #3
      Re: Portable typecast

      Henrik Goldman napsal:
      Hi,
      >
      I have a piece of code which looks like the following:
      >
      void f2(int i)
      {
      >
      }
      >
      void f1(HANDLE h, const void *pSetting1, const void *pSetting2)
      {
      switch(...)
      {
      case ABC:
      f2((int) pSetting1);
      }
      }
      >
      Assuming f1 takes a void pointer (actually two of them but it doesn't
      matter) I need to call f2 where I know that the variable really holds an
      integer.
      Due to compatibility with C the function f1 needs to be with C declaration
      and for this reason I cannot use function overloading with different
      parameters depending on the input type. Therefore it's assumed that f1() can
      take input of various types such as integers or pointers of specific types.
      In the example above I want to cast the void pointer to an integer but this
      fails on 64 bit platforms due to the fact that it goes from 64 bit to 32.
      On platforms with gcc I've previously used constructs like (int) (unsigned
      long) since unsigned long is 64 bit wide on those platforms. However this
      could cause problems with Win64 since Microsoft uses another 64 bit model
      then commonly used under unix.
      How would I cast this in platform independent way to ensure that the result
      would be as expected on both 32 and 64 bit platforms?
      Hi. You can pass in void pointer pointer to int and cast it to correct
      pointer type in function.

      Something like:

      void fn(void* pSettings)
      {
      int* pInt = (int*)pSettings ;
      // Use pInt here
      }

      Comment

      • Henrik Goldman

        #4
        Re: Portable typecast

        You probably need to post this question on the Microsoft win32
        newsgroup. You might find answers there. or else just search for
        ULONG_PTR in there. I am sure you would get the answer.
        >
        But it's not a Microsoft specific question. Currently I made things working
        on Windows by using: (int) (unsigned long long) but then some unix compilers
        are complaining about this construct (using gcc 3.3+).

        -- Henrik


        Comment

        • Henrik Goldman

          #5
          Re: Portable typecast

          >
          void fn(void* pSettings)
          {
          int* pInt = (int*)pSettings ;
          // Use pInt here
          }
          >
          Would this not cause new problems?
          Are you talking about using pInt directly as an integer? Otherwise the users
          would change:

          fn(123);

          to:
          int dummy = 123;
          fn(&dummy);

          This would not exactly be for the better since it would go against
          simplicity.

          -- Henrik


          Comment

          • Erik Wikström

            #6
            Re: Portable typecast

            On 2006-11-28 21:48, Henrik Goldman wrote:
            >>
            >void fn(void* pSettings)
            >{
            > int* pInt = (int*)pSettings ;
            > // Use pInt here
            >}
            >>
            >
            Would this not cause new problems?
            Are you talking about using pInt directly as an integer? Otherwise the users
            would change:
            >
            fn(123);
            >
            to:
            int dummy = 123;
            fn(&dummy);
            >
            This would not exactly be for the better since it would go against
            simplicity.
            Create the copy in the function then:

            void fn(void* pSettings)
            {
            int Int = *((int*)pSettin gs);
            // Use Int here
            }

            Of course users would still have to use the address-of operator when
            pasing arguments that are not pointers.

            --
            Erik Wikström

            Comment

            • Ondra Holub

              #7
              Re: Portable typecast


              Henrik Goldman napsal:

              void fn(void* pSettings)
              {
              int* pInt = (int*)pSettings ;
              // Use pInt here
              }
              >
              Would this not cause new problems?
              Are you talking about using pInt directly as an integer? Otherwise the users
              would change:
              >
              fn(123);
              This shouldn't be possible (123 is not pointer). There may be problem
              with 0 (zero), because it is also valid pointer value in C++, but I do
              not see there big problem.
              >
              to:
              int dummy = 123;
              fn(&dummy);
              Yes, that's the way how I meant it.

              Comment

              • Ondra Holub

                #8
                Re: Portable typecast


                Henrik Goldman napsal:

                void fn(void* pSettings)
                {
                int* pInt = (int*)pSettings ;
                // Use pInt here
                }
                >
                Would this not cause new problems?
                Are you talking about using pInt directly as an integer? Otherwise the users
                would change:
                >
                fn(123);
                >
                to:
                int dummy = 123;
                fn(&dummy);
                >
                This would not exactly be for the better since it would go against
                simplicity.
                >
                -- Henrik
                You can provide to user set of functions with correct parameters and
                then call this one generic function, which is declared as static, so
                user's cannot call it from other source files.

                If you need some "variant" type with C interface, you can also use
                union.

                Comment

                • David Harmon

                  #9
                  Re: Portable typecast

                  On Tue, 28 Nov 2006 16:19:40 +0100 in comp.lang.c++, "Henrik Goldman"
                  <henrik_goldman @mail.tele.dkwr ote,
                  >Due to compatibility with C the function f1 needs to be with C declaration
                  >and for this reason I cannot use function overloading with different
                  >parameters depending on the input type.
                  Overloading of functions in this situation gets you nothing more than
                  cleaner notation. The same thing can be accomplished with C
                  compatibility with a set of functions named
                  f1_int(int);
                  f1_double(doubl e);
                  etc. This is basically what some C++ compilers do to implement
                  overloaded functions anyway, with "name mangling" for the linker.

                  Comment

                  Working...