Getting rid of pointer to function cast warning

M

Miguel Guedes

Is it possible to get rid of the warning below generated at compile time
without resorting to any compiler directive trickery? (ie. pragmas and
the likes)

Both g++ and clang++ report the following warning when casting a void *
pointer retrieved from dlsym (after loading an SO dynamic library.)

warning: cast between pointer-to-function and
pointer-to-object is an extension [-pedantic]
if(!(fn_main = reinterpret_cast<Omnisource* (*)(void *)>(
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Relevant bit of code:

if(!(fn_main = reinterpret_cast<Omnisource* (*)(void *)>(
dlsym(handle, "omnisource_main"))))
throw std::runtime_error(dlerror());
 
N

Nobody

Chris Vine said:
[1] POSIX says: "The ISO C standard does not require that pointers to
functions can be cast back and forth to pointers to data. However,
POSIX-conforming implementations are required to support this, as noted
in Pointer Types. The result of converting a pointer to a function
into a pointer to another data type (except void *) is still undefined,
however."

I believe that the reason why the C standard doesn't want to make the
guarantee is as to not force a pointer-to-data and a pointer-to-function
to have the same size. It's not inconceivable that those two types of
pointers might have different sizes in some architectures.

It's not inconceivable that pointer-to-void and pointer-to-int might have
different sizes in some architectures, yet the C standard specifically
allows for that.

AIUI, the issue is more in case a given architecture doesn't actually
support the concept of pointer-to-function, at least not in the sense of
anything that would normally be considered a pointer.
POSIX disregards such a possibility.

As well as dlsym(), the same issue would arise with mmap(..., PROT_EXEC)
(which is probably used to implement dlsym()), mlock(), mprotect() etc.
 
M

Miguel Guedes

Casting an object pointer (void*) to function pointer (or vice versa) is
a POSIX extension, not supported in pure C/C++, although it must be
supported by your compiler if it is to be POSIX compliant, as it is
required by dlsym() [1]. The canonical example given in the POSIX
documentation for dlsym() to avoid compiler warnings is as follows:

int (*fptr)(int);
*(void **)(&fptr) = dlsym(handle, "my_function");

In other words, you take the address of your function pointer, cast it
to void** and then dereference that back to void*.

However, you will probably find that with your level of warning, this
gives a strict aliasing warning instead of an unlawful cast warning.
You can overcome that, with gcc, by using a union, but that is
strictly not kosher either. Pick your poison. Personally I would stay
with your reinterpret_cast.

You're right; better to just stay with reinterpret_cast! Thanks for the
wonderfully detailed explanation, Chris.
The best thing is not to set your warnings to the -pedantic level, so
requiring strict C/C++ compliance, if you are using POSIX extensions.

Chris

[1] POSIX says: "The ISO C standard does not require that pointers to
functions can be cast back and forth to pointers to data. However,
POSIX-conforming implementations are required to support this, as noted
in Pointer Types. The result of converting a pointer to a function
into a pointer to another data type (except void *) is still undefined,
however."
 

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,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top