Portable typecast

Discussion in 'C++' started by Henrik Goldman, Nov 28, 2006.

  1. 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
     
    Henrik Goldman, Nov 28, 2006
    #1
    1. Advertising

  2. Henrik Goldman

    Guest

    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.
     
    , Nov 28, 2006
    #2
    1. Advertising

  3. Henrik Goldman

    Ondra Holub Guest

    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
    }
     
    Ondra Holub, Nov 28, 2006
    #3
  4. > 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
     
    Henrik Goldman, Nov 28, 2006
    #4
  5. >
    > 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
     
    Henrik Goldman, Nov 28, 2006
    #5
  6. 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*)pSettings);
    // 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
     
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=, Nov 28, 2006
    #6
  7. Henrik Goldman

    Ondra Holub Guest

    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.
     
    Ondra Holub, Nov 28, 2006
    #7
  8. Henrik Goldman

    Ondra Holub Guest

    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.
     
    Ondra Holub, Nov 28, 2006
    #8
  9. Henrik Goldman

    David Harmon Guest

    On Tue, 28 Nov 2006 16:19:40 +0100 in comp.lang.c++, "Henrik Goldman"
    <> wrote,
    >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(double);
    etc. This is basically what some C++ compilers do to implement
    overloaded functions anyway, with "name mangling" for the linker.
     
    David Harmon, Nov 29, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Eli Bendersky
    Replies:
    1
    Views:
    1,170
    Mike Treseler
    Mar 1, 2006
  2. Mark Fitzpatrick

    Re: typecast error!

    Mark Fitzpatrick, Feb 1, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    1,673
    Lau Lei Cheong
    Feb 8, 2006
  3. Joe Van Meer

    Re: typecast error!

    Joe Van Meer, Feb 1, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    421
    Bob Lehmann
    Feb 2, 2006
  4. Otis Mukinfus

    Re: typecast error!

    Otis Mukinfus, Feb 3, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    372
    Terry Burns
    Feb 4, 2006
  5. Replies:
    7
    Views:
    920
Loading...

Share This Page