Portable typecast

H

Henrik Goldman

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
 
A

amparikh

Henrik said:
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.
 
O

Ondra Holub

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
}
 
H

Henrik Goldman

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
 
H

Henrik Goldman

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
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

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.
 
O

Ondra Holub

Henrik Goldman napsal:
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.
 
O

Ondra Holub

Henrik Goldman napsal:
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.
 
D

David Harmon

On Tue, 28 Nov 2006 16:19:40 +0100 in comp.lang.c++, "Henrik Goldman"
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top