Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Casting void* to function pointer

2,888 views
Skip to first unread message

Rafal Dabrowa

unread,
Jun 22, 2002, 2:00:06 PM6/22/02
to
I have a trouble with converting a variable type void*
to a function pointer. I have two variables:
void *pVoid;
void (*pFun)();
I know, that pVoid holds a function pointer (namely,
a value returned by dlsym() UNIX function).
How to cast safely pVoid to pFun using new-style
casting ? I have tried:
pFun = reinterpret_cast<void(*)()>(pVoid);
but my compiler (g++) complains, that
"ANSI C++ forbids casting between pointers to
function and objects". Is it really true ?
I have tried another way:
long addr = reinterpret_cast<long>(pVoid);
pFun = reinterpret_cast<void(*)()>(addr);
This compiles fine, but does not work on machines,
where sizeof(long) < sizeof(void*).

Maybe is it a "bug" in ANSI standard ? Why I am
forced to use less safe second way of casting instead
of using more safe (in my opinion), but forbidden by
ANSI, first way of casting ?

Rafal Dabrowa

If you answer directly to my e-mail address, remove
"nospam." and "no-spam." parts.

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Marco Manfredini

unread,
Jun 23, 2002, 9:03:36 AM6/23/02
to
"Rafal Dabrowa" <no-spam....@f2virt.onet.pl> wrote:

> I have a trouble with converting a variable type void*
> to a function pointer. I have two variables:
> void *pVoid;
> void (*pFun)();
> I know, that pVoid holds a function pointer (namely,
> a value returned by dlsym() UNIX function).
> How to cast safely pVoid to pFun using new-style
> casting ? I have tried:
> pFun = reinterpret_cast<void(*)()>(pVoid);
> but my compiler (g++) complains, that
> "ANSI C++ forbids casting between pointers to
> function and objects". Is it really true ?

Yes. This rule tries to acknowledge that there are system
architectures where function pointers have a different size than
memory pointers (or point to different memory spaces: probably still
common among DSP, but some will remember this from (yuck) 16-Bit
Windows and/or Dos programming). Just think of the member function
pointers, that aren't convertible either.

Forbidding this protects your code from being broken by
revolutionary advances in compiler or processor technology.
Theoretically.

> I have tried another way:
> long addr = reinterpret_cast<long>(pVoid);
> pFun = reinterpret_cast<void(*)()>(addr);
> This compiles fine, but does not work on machines,
> where sizeof(long) < sizeof(void*).

Or sizeof(void*)!=sizeof(void(*)(void)). The latter is how dlsym's
return value should be declared instead. Since the old kind of
casting still works for compatibility reasons, you can define an
operation to do the neccesary conversion in the style of the other
casting operators:

template<typename D>
struct unsafe_cast // not fools proof as well
{
D &d;
template<typename S>
inline unsafe_cast(S& s) : d((D&)s) {}
inline operator D& () { return d; }
};

int main()
{
void *k;
void (*fn)(void);
fn=unsafe_cast<void(*)(void)>(k);
}

Don't worry about the appearent overhead. The compiler will
transform this into the same sequence of code that applying the
(cast) would generate.

Marco

Ross Smith

unread,
Jun 23, 2002, 9:04:31 AM6/23/02
to
Rafal Dabrowa wrote:

> I have a trouble with converting a variable type void*
> to a function pointer. I have two variables:
> void *pVoid;
> void (*pFun)();
> I know, that pVoid holds a function pointer (namely,
> a value returned by dlsym() UNIX function).
> How to cast safely pVoid to pFun using new-style
> casting ? I have tried:
> pFun = reinterpret_cast<void(*)()>(pVoid);
> but my compiler (g++) complains, that
> "ANSI C++ forbids casting between pointers to
> function and objects". Is it really true ?
> I have tried another way:
> long addr = reinterpret_cast<long>(pVoid);
> pFun = reinterpret_cast<void(*)()>(addr);
> This compiles fine, but does not work on machines,
> where sizeof(long) < sizeof(void*).

Your compiler is being overly paranoid. The Unix standard requires void*
to be capable of holding a function pointer, and I would have expected
a Unix compiler to be aware of that.

You could avoid going through a long by using a union:

union vp2fp {
void* vp;
void (*fp)();
};
vp2fp u;
u.vp = pVoid;
pFun = u.fp;

But that may not work if void* and function pointers aren't the same
size. You could also try using a C-style cast:

pFun = (void(*)())pVoid;

The compiler may be more forgiving in that case. If that doesn't work, I
can only suggest complaining to the compiler vendor.

--
Ross Smith ..................................... Auckland, New Zealand
r-s...@ihug.co.nz ...................................................

"Never underestimate the power of stupid things in large numbers."
-- Serious Sam

John Potter

unread,
Jun 23, 2002, 9:04:59 AM6/23/02
to
On 22 Jun 2002 14:00:06 -0400, "Rafal Dabrowa"
<no-spam....@f2virt.onet.pl> wrote:

> I have a trouble with converting a variable type void*
> to a function pointer. I have two variables:
> void *pVoid;
> void (*pFun)();
> I know, that pVoid holds a function pointer (namely,
> a value returned by dlsym() UNIX function).

You know that you are platform specific and that it will work.

> How to cast safely pVoid to pFun using new-style
> casting ? I have tried:
> pFun = reinterpret_cast<void(*)()>(pVoid);
> but my compiler (g++) complains, that
> "ANSI C++ forbids casting between pointers to
> function and objects". Is it really true ?

Yes. There is no conversion between pointer to object and pointer to
function.

> I have tried another way:
> long addr = reinterpret_cast<long>(pVoid);
> pFun = reinterpret_cast<void(*)()>(addr);

It might be better to use unsigned long.

> This compiles fine, but does not work on machines,
> where sizeof(long) < sizeof(void*).

Nor on machines where sizeof(long) < sizeof(function*). They exist.

You are on a un*x box where you know that sizeof(long) ==
sizeof(void*) == sizeof(function*) and can expect your implementation
to do the right thing. All reinterpret_casts are implementation
defined anyway.

> Maybe is it a "bug" in ANSI standard ? Why I am
> forced to use less safe second way of casting instead
> of using more safe (in my opinion), but forbidden by
> ANSI, first way of casting ?

There is nothing safe about casts in general, and especially
reinterpret_cast.

Some implementations on un*x boxes allow a C style cast as an
extension. Try it.

John

Erik Max Francis

unread,
Jun 24, 2002, 6:57:59 AM6/24/02
to
Ross Smith wrote:

> Your compiler is being overly paranoid. The Unix standard requires
> void*
> to be capable of holding a function pointer, and I would have expected
> a Unix compiler to be aware of that.

The new-style casts follow the C++ Standard, not UNIX Standards. If you
want to cast data pointers and function pointers, which is illegal under
the C Standard, you should use the legacy C-style cast.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ See the son in your bad day / Smell the flowers in the valley
\__/ Chante Moore
Bosskey.net: Aliens vs. Predator 2 / http://www.bosskey.net/avp2/
A personal guide to Aliens vs. Predator 2.

James Kanze

unread,
Jun 24, 2002, 7:09:53 AM6/24/02
to
"Rafal Dabrowa" <no-spam....@f2virt.onet.pl> writes:

|> I have a trouble with converting a variable type void* to a
|> function pointer.

Not surprising. There are no conversions between void* and pointers
to functions. On some implementations (I have used them), a pointer
to a function may even be bigger than a void*.

|> I have two variables:
|> void *pVoid;
|> void (*pFun)();
|> I know, that pVoid holds a function pointer (namely, a value
|> returned by dlsym() UNIX function). How to cast safely pVoid to
|> pFun using new-style casting ?

By counting on other standards than just C++. Posix guarantees that
function pointers and void* have the same size. Posix doesn't have a
C++ binding, as far as I know, but 1) it guarantees that in C, a C
style cast between the two works, and 2) the C++ standard defines a C
style cast (in C++) as having a semantic equivalent to either a
static_cast or a reinterpret_cast. Since the static_cast isn't legal
in this case, I would interpret that, combining the Posix and the C++
standards, a reinterpret_cast is guaranteed to have the desired
results (and, exceptionally, be safe).

In fact, I the C++ standard officially forbids this case. This is
not, however, the first time that Posix standards contradict language
standards. (Posix requires some things in <stdio.h>, for example,
that the C standard doesn't allow.) Any reasonable compiler has to
make some sort of compromise -- typically, there will be compiler
flags to compile according to Posix, and different flags to adhere
strictly to the language standard.

|> I have tried:
|> pFun = reinterpret_cast<void(*)()>(pVoid);
|> but my compiler (g++) complains, that
|> "ANSI C++ forbids casting between pointers to
|> function and objects". Is it really true ?

It's true, see above. In the case of g++, it is a real problem,
because, of course, g++ *isn't* (and shouldn't be) a "Posix" compiler.
Still, given the importance of Posix systems for g++, I would expect
some sort of hack, much as that the purveyors of Posix systems have
had to do.

Of course, the "best" solution (for some special definition of best)
is to provide wrapper functions (written in C) for the Posix
functions, with a clean interface.

|> I have tried another way:
|> long addr = reinterpret_cast<long>(pVoid);
|> pFun = reinterpret_cast<void(*)()>(addr);
|> This compiles fine, but does not work on machines,
|> where sizeof(long) < sizeof(void*).

Do you know of any Posix machines where this is the case? Does Posix
even allow it?

|> Maybe is it a "bug" in ANSI standard ? Why I am forced to use less
|> safe second way of casting instead of using more safe (in my
|> opinion), but forbidden by ANSI, first way of casting ?

A more reasonable question would be why Posix defines an interface
which depends on undefined behavior (in C) or illegal behavior (in
C++).

--
James Kanze mailto:jka...@caicheuvreux.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
Tel. +33 1 41 89 80 93

James Kanze

unread,
Jun 24, 2002, 11:32:49 AM6/24/02
to
Ross Smith <r-s...@ihug.co.nz> wrote in message
news:<af3aje$lrh$1...@lust.ihug.co.nz>...
> Rafal Dabrowa wrote:

> > I have a trouble with converting a variable type void*
> > to a function pointer. I have two variables:
> > void *pVoid;
> > void (*pFun)();
> > I know, that pVoid holds a function pointer (namely,
> > a value returned by dlsym() UNIX function).
> > How to cast safely pVoid to pFun using new-style
> > casting ? I have tried:
> > pFun = reinterpret_cast<void(*)()>(pVoid);
> > but my compiler (g++) complains, that
> > "ANSI C++ forbids casting between pointers to
> > function and objects". Is it really true ?
> > I have tried another way:
> > long addr = reinterpret_cast<long>(pVoid);
> > pFun = reinterpret_cast<void(*)()>(addr);
> > This compiles fine, but does not work on machines,
> > where sizeof(long) < sizeof(void*).

> Your compiler is being overly paranoid. The Unix standard requires
> void* to be capable of holding a function pointer, and I would have
> expected a Unix compiler to be aware of that.

The C++ standard requires a diagnostic.

His compiler is g++. G++ isn't a (only) Unix compiler.

That said, yes, there should be an option to allow the use of
reinterpret_cast in this case.

> You could avoid going through a long by using a union:

> union vp2fp {
> void* vp;
> void (*fp)();
> };
> vp2fp u;
> u.vp = pVoid;
> pFun = u.fp;

> But that may not work if void* and function pointers aren't the same
> size. You could also try using a C-style cast:

> pFun = (void(*)())pVoid;

> The compiler may be more forgiving in that case. If that doesn't
> work, I can only suggest complaining to the compiler vendor.

He might try a C-style cast. Or simply wrap the function with a
typesafe wrapper written in C. (The cast is undefined behavior in C,
and does not require a diagnostic.)

--
James Kanze mailto:jka...@caicheuvreux.com

Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)69 63198627

Alexander Terekhov

unread,
Jun 24, 2002, 11:59:26 AM6/24/02
to

James Kanze wrote:
[...]

> |> Maybe is it a "bug" in ANSI standard ? Why I am forced to use less
> |> safe second way of casting instead of using more safe (in my
> |> opinion), but forbidden by ANSI, first way of casting ?
>
> A more reasonable question would be why Posix defines an interface
> which depends on undefined behavior (in C) or illegal behavior (in
> C++).

Uhmm. How about this; I guess, sort of 'answer' [or perhaps even
'some-sort-of-hack' ;-) ] w.r.t. the "more reasonable question":

http://www.opengroup.org/austin/docs/austin_110r2.txt

"Document Number: AUSTIN/110r1

Title: XSHft Aardvark Change Request Report

Revision Date: 2002-06-21

Source: Andrew Josey, Chair

Action: for review

This report contains the dispositions of the aardvark comments
submitted against the XSH final text.

....

_____________________________________________________________________________
COMMENT Enhancement Request Number 13
mse...@yahoo.com Defect in XSH dlsym (rdvk# 35)
{0} Tue, 16 Apr 2002 22:40:04 +0100 (BST)
_____________________________________________________________________________
Accept_____ Accept as marked below_X___ Duplicate_____ Reject_____
Rationale for rejected or partial changes:


This enhancement request is being handled partially
as an interpretation request, some input will also be put into
the TC to document the issue.

Overview: The standard is clear and conforming implementations must
behave as described.

The dlsym() function is marked as part of the X/Open System Interfaces
Extension (by the XSI margin marking). Systems conforming to the
X/Open Systems Interfaces Extension are indeed required to be able to
convert between function pointers and void * data pointers without
losing data. This is most clearly stated in the description of the
va_arg() macro in the description of <stdarg.h> (XBD, P310,
L11109-11119) where the XSI shading on L11119 indicates that
implementations supporting the X/Open System Interfaces Extension are
required to be able to handle pointers to any type of object, not just
pointers to data.

The XSI margin marking description clearly states that requirements
like this are extensions to the requirements of the C Standard. In
this case, the 1999 C Standard does indeed require a warning to be
issued for the function call shown in the dlsym() examples section on
XSH P259, L8566. An equivalent form of this call:
*(void **)(&fptr) = dlsym(handle, "my_function");
does not generate compiler warnings and will work correctly on all
systems supporting the X/Open System Interfaces Extension.

Notes to the Editor:
In TC1 make the following changes:
1. XSH P259, L8566 (EXAMPLES): Change from:
fptr = (int (*)(int))dlsym(handle, "my_function");
to:
*(void **)(&fptr) = dlsym(handle, "my_function");
2. XSH P260, L8590 (RATIONALE): Change from:
None.
to:
The C Standard does not require that pointers to functions can
be cast back and forth to pointers to data. Indeed, the C
Standard does not require that an object of type void * can
hold a pointer to a function. Systems supporting the X/Open
System Interfaces Extension, however, do require that an object
of type void * can hold a pointer to a function. The result of
converting a pointer to a function into a pointer to another
data type (except void *) is still undefined, however. Note
that compilers conforming to the C Standard are required to
generate a warning if a conversion from a void * pointer to a
function pointer is attempted as in:
fptr = (int (*)(int))dlsym(handle, "my_function");

Due to the problem noted here a future revision may either
add a new function to return function pointers, or the
current interface may be deprecated in favor of two new functions,
one that returns data pointers, and the other that returns
function pointers.
_____________________________________________________________________________
Page: 259 Line: 8540 Section: dlsym


Problem:

Defect code : 2. Omission

The "dlsym()" function is defined as returning "the address of a
symbol". According to the Example, "dlsym ()can be used to access
either function or data objects". The return type of dlsym is a "void
*".

In order to actually call a function using the pointer returned by
"dlsym()", the pointer must be converted from a "void *" type to a
pointer to function type. However, the ISO C Standard says that
converting a "void *" type to a pointer to function type results in
undefined behavior. At least one major compiler reports a warning when
attempting such a conversion, even with an explicit cast.

Action:

I would like a new function added that returns the address of a function
object symbol and whose return type is a function pointer. For
example:

fptr_t dlsym_f(void *restrict handle, const char *restrict name);

Standard C requires that a pointer to a function of one type may be
converted to a pointer to a function of another type and back again, and
the result shall compare equal to the original pointer. Therefore,
"fptr_t" can be defined as any pointer to function type.

The "dlsym()" function could continue to be used for data objects. As
an extension, implementations that allow converting from "void *" to
pointer to function types could continue to allow using "dlsym()" in
addition to "dlsym_f()" for function objects. This would allow
backwards compatability, while offering a more portable option for new
code.

_____________________________________________________________________________

...."

regards,
alexander.

Alexander Terekhov

unread,
Jun 24, 2002, 1:58:10 PM6/24/02
to

Rafal Dabrowa wrote:
>
> I have a trouble with converting a variable type void*
> to a function pointer. I have two variables:
> void *pVoid;
> void (*pFun)();
> I know, that pVoid holds a function pointer (namely,
> a value returned by dlsym() UNIX function).
> How to cast safely pVoid to pFun using new-style
> casting ? I have tried:
> pFun = reinterpret_cast<void(*)()>(pVoid);
> but my compiler (g++) complains, that
> "ANSI C++ forbids casting between pointers to
> function and objects". Is it really true ?
> I have tried another way:
> long addr = reinterpret_cast<long>(pVoid);
> pFun = reinterpret_cast<void(*)()>(addr);
> This compiles fine, but does not work on machines,
> where sizeof(long) < sizeof(void*).
>
> Maybe is it a "bug" in ANSI standard ? Why I am
> forced to use less safe second way of casting instead
> of using more safe (in my opinion), but forbidden by
> ANSI, first way of casting ?

< see my other message on POSIX.1/dlsym() I've recently posted to this thread >

lnxmuell:/usr/terekhov # g++ -v
Reading specs from /usr/lib/gcc-lib/s390-suse-linux/2.95.3/specs
gcc version 2.95.3 20010315 (SuSE)
lnxmuell:/usr/terekhov # g++ -o fp fp.cpp
lnxmuell:/usr/terekhov # ./fp

1 0x400938 1

+---------------------------------------------------------+
| How about 'The Right Java(tm)'-std ~= 'WG14+WG15+WG21'? |
| INCLUDING XSH-C extensions + brand new XSH-C++ bindings |
+---------------------------------------------------------+
| POSIX.1++ [aka 'Right Thing: ++<C;C++;POSIX.1>'] RULES! |
+---------------------------------------------------------+

+---------------------------------------------------------+
| How about 'The Right Java(tm)'-std ~= 'WG14+WG15+WG21'? |
| INCLUDING XSH-C extensions + brand new XSH-C++ bindings |
+---------------------------------------------------------+
| POSIX.1++ [aka 'Right Thing: ++<C;C++;POSIX.1>'] RULES! |
+---------------------------------------------------------+

+---------------------------------------------------------+
| How about 'The Right Java(tm)'-std ~= 'WG14+WG15+WG21'? |
| INCLUDING XSH-C extensions + brand new XSH-C++ bindings |
+---------------------------------------------------------+
| POSIX.1++ [aka 'Right Thing: ++<C;C++;POSIX.1>'] RULES! |
+---------------------------------------------------------+

1 0x400938 1
lnxmuell:/usr/terekhov # cat fp.cpp

#include <cstdlib>
#include <iostream>
using namespace std;

void f()
{
cout << endl
<< "+---------------------------------------------------------+" << endl
<< "| How about 'The Right Java(tm)'-std ~= 'WG14+WG15+WG21'? |" << endl
<< "| INCLUDING XSH-C extensions + brand new XSH-C++ bindings |" << endl
<< "+---------------------------------------------------------+" << endl
<< "| POSIX.1++ [aka 'Right Thing: ++<C;C++;POSIX.1>'] RULES! |" << endl
<< "+---------------------------------------------------------+" << endl;
}

void* pVoid; // = f;
// Thank you for testing your code with Comeau C/C++!
// Your Comeau C/C++ test results are as follows:
//
// Comeau C/C++ 4.3.0 (May 10 2002 12:47:52)
// Copyright 1988-2002 Comeau Computing. All rights reserved.
//
// "9423.c", line 17: error: a value of type "void (*)()" cannot be used to
// initialize an entity of type "void *"
// void* pVoid = f;
// ^
//
// 1 error detected in the compilation of "9423.c".
//
// Tell others about http://www.comeaucomputing.com/tryitout !
// In strict mode, with -tused, Compile failed

void (*pFun)();

int main()
{
*reinterpret_cast<void(**)()>(&pVoid) = f;
// pFun = reinterpret_cast<void(*)()>(pVoid);
*reinterpret_cast<void**>(&pFun) = pVoid;
cout << endl << f << ' ' << pVoid << ' ' << pFun << endl;
f();
pFun();
pFun = *reinterpret_cast<void(**)()>(&pVoid);
pFun();
cout << endl << f << ' ' << pVoid << ' ' << pFun << endl;
return EXIT_SUCCESS;
// Thank you for testing your code with Comeau C/C++!
// Your Comeau C/C++ test results are as follows:
//
// Comeau C/C++ 4.3.0 (May 10 2002 12:47:52)
// Copyright 1988-2002 Comeau Computing. All rights reserved.
//
//
// Tell others about http://www.comeaucomputing.com/tryitout !
// In strict mode, with -tused, Compile succeeded (but remember,
// the Comeau online compiler does not link).
}

lnxmuell:/usr/terekhov #

regards,
alexander

P.S.

D:\>cl -GX -W3 fp.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

fp.cpp
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:fp.exe
fp.obj

D:\>fp

0040107E 0040107E 0040107E

+---------------------------------------------------------+
| How about 'The Right Java(tm)'-std ~= 'WG14+WG15+WG21'? |
| INCLUDING XSH-C extensions + brand new XSH-C++ bindings |
+---------------------------------------------------------+
| POSIX.1++ [aka 'Right Thing: ++<C;C++;POSIX.1>'] RULES! |
+---------------------------------------------------------+

+---------------------------------------------------------+
| How about 'The Right Java(tm)'-std ~= 'WG14+WG15+WG21'? |
| INCLUDING XSH-C extensions + brand new XSH-C++ bindings |
+---------------------------------------------------------+
| POSIX.1++ [aka 'Right Thing: ++<C;C++;POSIX.1>'] RULES! |
+---------------------------------------------------------+

+---------------------------------------------------------+
| How about 'The Right Java(tm)'-std ~= 'WG14+WG15+WG21'? |
| INCLUDING XSH-C extensions + brand new XSH-C++ bindings |
+---------------------------------------------------------+
| POSIX.1++ [aka 'Right Thing: ++<C;C++;POSIX.1>'] RULES! |
+---------------------------------------------------------+

0040107E 0040107E 0040107E

D:\>

Michiel Salters

unread,
Jun 25, 2002, 5:48:21 AM6/25/02
to
"Rafal Dabrowa" <no-spam....@f2virt.onet.pl> wrote in message news:<af2209$g2v$1...@news.tpi.pl>...

> I have a trouble with converting a variable type void*
> to a function pointer. I have two variables:
> void *pVoid;
> void (*pFun)();
> I know, that pVoid holds a function pointer (namely,
> a value returned by dlsym() UNIX function).
> How to cast safely pVoid to pFun using new-style
> casting ? I have tried:
> pFun = reinterpret_cast<void(*)()>(pVoid);
> but my compiler (g++) complains, that
> "ANSI C++ forbids casting between pointers to
> function and objects". Is it really true ?

This is Core Issue 195, which is still open. I've got
drafting ready to make the reinterpret_cast ( and thus
also the C-style cast ) legal, but for now GCC is right
and it doesn't have a choice.
With the fix, GCC would still have a right but no obligation
to complain. ( Assumes the proposal is accepted )

Regards,
--
Michiel Salters

Daniel Spangenberg

unread,
Oct 7, 2002, 12:36:26 PM10/7/02
to
Hi Rafal Dabrowa,

I would recommend the following solution of your dilemma by using the
"boost"-way to do it from boost/function/function_base.hpp. Here the
corresponding quote:

>>
/**
* A union of a function pointer and a void pointer. This is
necessary
* because 5.2.10/6 allows reinterpret_cast<> to safely cast
between
* function pointer types and 5.2.9/10 allows static_cast<> to
safely
* cast between a void pointer and an object pointer. But it is not
legal
* to cast between a function pointer and a void* (in either
direction),
* so function requires a union of the two. */
union any_pointer
{
void* obj_ptr;
const void* const_obj_ptr;
void (*func_ptr)();

explicit any_pointer(void* p) : obj_ptr(p) {}
explicit any_pointer(const void* p) : const_obj_ptr(p) {}
explicit any_pointer(void (*p)()) : func_ptr(p) {}
};
<<

Greetings from Germany,

Daniel Spangenberg


Rafal Dabrowa schrieb:

> I have a trouble with converting a variable type void*
> to a function pointer. I have two variables:
> void *pVoid;
> void (*pFun)();
> I know, that pVoid holds a function pointer (namely,
> a value returned by dlsym() UNIX function).
> How to cast safely pVoid to pFun using new-style
> casting ? I have tried:
> pFun = reinterpret_cast<void(*)()>(pVoid);
> but my compiler (g++) complains, that
> "ANSI C++ forbids casting between pointers to
> function and objects". Is it really true ?
> I have tried another way:
> long addr = reinterpret_cast<long>(pVoid);
> pFun = reinterpret_cast<void(*)()>(addr);

0 new messages