can void* be used to store function pointers?

5.7k views Asked by At

void* is defined in such a way that it could point any thing. So can it be used to point a function (int send())?

int send();
void* p = send;

Is it possible? When i use like this it is not showing me errors why? If not, Is there any way to store all pointers in a single variable?

2

There are 2 answers

7
Vlad from Moscow On BEST ANSWER

No it may not.

According to the C Standard (6.3.2.3 Pointers)

1 A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

As for function pointers then

8 A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.

In the C++ Standard there is more detailed definition of pointers (3.9.2 Compound types)

3 The type of a pointer to void or a pointer to an object type is called an object pointer type....The type of a pointer that can designate a function is called a function pointer type.

And

4 A pointer to cv-qualified (3.9.3) or cv-unqualified void can be used to point to objects of unknown type. Such a pointer shall be able to hold any object pointer. An object of type cv void* shall have the same representation and alignment requirements as cv char*.

3
James Kanze On

Maybe. Until C++11, they couldn't; but C++11 adds:

Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cvqualification, shall yield the original pointer value.

This doesn't appear to have made it into C yet.

The reason why you can't convert between them, of course, is because they may not have the same size or format. Posix requires that they do have the same size and format, and I would expect all Posix compilers to support the conversion; most did before anyway, even though it made them non-conformant.

EDIT:

A little more information. After rereading the C standard, I think conversions between object pointers and function pointers are undefined behavior: the C standard doesn't seem to require a diagnostic in this case, but it definitely doesn't define any behavior for it. As undefined behavior, an implementation (or Posix) is free to define it. Or just do anything it wants, without documenting it.

On the otherhand, C++, pre C++11, required a diagnostic (although a number of compilers didn't give one). In C++11, as per the paragraph quoted above, it is implementation defined whether an implementation supports it or not, and if an implementation supports it, they are required to document its behavior. So in all cases, an implementation is required to document what it does, and if it does not support it, it is required to issue a diagnostic if the code tries to do the conversion.