Reputation: 20736
Am i wrong about the following?
C++ standards says that conversion between pointer-to-function and pointer-to-object (and back) is conditionnaly-supported with implementation-defined semantics, while all C standards says that this is illegal in all cases, right?
void foo() {}
int main(void)
{
void (*fp)() = foo;
void* ptr = (void*)fp;
return 0;
}
ISO/IEC 14882:2011
5.2.10 Reinterpret cast [expr.reinterpret.cast]
8 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.
I can't find anything about it in C standard right now...
Upvotes: 16
Views: 7797
Reputation: 126185
The POSIX standard specifies:
2.12.3 Pointer Types
All function pointer types shall have the same representation as the type pointer to void. Conversion of a function pointer to void * shall not alter the representation. A void * value resulting from such a conversion can be converted back to the original function pointer type, using an explicit cast, without loss of information.
Note: The ISO C standard does not require this, but it is required for POSIX conformance.
This requirement ends up meaning that any C or C++ compiler that wants to be able to support POSIX will support this kind of casting.
Upvotes: 1
Reputation: 2881
Though the behavior of the cast is not defined by the "core" of the standard, this case is explicitly described as invalid in the C99 rationale document (6.3.2.3, Pointers):
Nothing is said about pointers to functions, which may be incommensurate with object pointers and/or integers.
Even with an explicit cast, it is invalid to convert a function pointer to an object pointer or a pointer to void, or vice versa.
And since it may be useful, it is also mentioned in the Annex J of the standard as a "common extension" (C11 Standard J.5.7, Function pointer casts):
A pointer to an object or to
void
may be cast to a pointer to a function, allowing data to be invoked as a function (6.5.4).A pointer to a function may be cast to a pointer to an object or to
void
, allowing a function to be inspected or modified (for example, by a debugger) (6.5.4).
Describing this as an extension means that this is not part of the standard requirements (but it wouldn't be needed, the omission of any explicit behavior is enough).
Upvotes: 5
Reputation: 33106
J.5.7 Function pointer casts
A pointer to an object or to void may be cast to a pointer to a function, allowing data to be invoked as a function (6.5.4).
A pointer to a function may be cast to a pointer to an object or to void, allowing a function to be inspected or modified (for example, by a debugger) (6.5.4).
Upvotes: 13
Reputation: 52274
In all C standards the conversion between pointer-to-function and pointer-to-object is not defined, in C++ before C++11, the conversion was not allowed and compilers had to give an error, but there were compilers which accepted the conversion for C and backward compatibility and because is useful for things like dynamically loaded libraries access (for instance the dlsym
POSIX function mandates its use). C++11 introduced the notion of conditionally-supported features an used it to adapt the standard with the existing practice. Now either the compiler should reject the program trying to do such conversion or it should respect the limited constraints given.
Upvotes: 5
Reputation: 272467
You're right, the C(99) standard says nothing about conversion from pointer-to-function to pointer-to-object, therefore it's undefined behaviour.*
Upvotes: 9