8

There is the code that I've written for experiments with reinterpret_cast<T>

#include <iostream>
#include <cstdlib>

using std::cout;
using std::endl;

int foo()
{
    cout << "foo" << endl;
    return 0;
}

void (*bar)();
int main()
{

    bar = reinterpret_cast<void (*)()>(foo); //Convertion a function type to a pointer to function type
    bar(); //displays foo. Is it UB?
}

First of all why such reinterpret_cast convertion permitted? I thought such conversion is ill-formed.

2
  • 1
    C++ allows you to shoot you in the foot in many interesting ways, and if you're lucky the compiler will give you a warning about it. However, if you disable the warnings or errors in any way, for example by using reinterpret_cast to cast one type to another (possibly incompatible) type many would say that you deserve what you get. Commented Aug 5, 2014 at 4:11
  • @JoachimPileborg But 5.2.10/1 said that conversions that could be performed explicitly using reinterpret_cast was listed below. No other conversion could be performed explicitly using reinterpret_cast. There is no such conversion in 5.2.10. Commented Aug 5, 2014 at 4:12

2 Answers 2

6

The standard (C++11 §5.2.10/6) says

A pointer to a function can be explicitly converted to a pointer to a function of a different type. The effect of calling a function through a pointer to a function type that is not the same as the type used in the definition of the function is undefined. Except that converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

So it is undefined behavior.

Sign up to request clarification or add additional context in comments.

7 Comments

How is that not clear? "A pointer to a function can be explicitly converted to a pointer to a function of a different type."
A function type is not the same as a pointer to function type.
It's clear. But I dont cast pointer to function to another pointer to function. I cast a function type to a pointer to function.
@St.Antario: That's true.. However, function type decays to function pointer type in virtually all contexts. The situation is very similar to what happens to arrays. The only contexts that prevent function type decay are unary & operator, sizeof operator and some others. reinterpret_cast is not an exception, which means that every time you specify function name as an operand, it gets implicitly converted to function pointer type. I.e. reinterpret_cast<>(foo) is exactly equivalent to reinterpret_cast<>(&foo).
@St.Antario From §4.3/1: "An lvalue of function type T can be converted to a prvalue of type “pointer to T.” The result is a pointer to the function."
|
2

Formally calling via the pointer casted to different function type is Undefined Behavior (by C++11 §5.2.10/6).

In practice you're casting away a function result of type int, that would be returned in a register. So about the worst that can happen when you call via the casted pointer, is that contrary to the compiler's expectations a register has changed value.

Another practical consideration: C++ does not support casting between function and data pointers, but Posix effectively requires cast to void* and back to work OK. The C++ restriction is presumably in support of Harvard architecture machines, where instructions are not retrieved via the same bus and memory as ordinary data. But the Posix round-trip would presumably work also on such architecture, unless the data address space was much smaller than the instruction address space.

1 Comment

To be clear: the cast is not UB; it's defined such that casting from function type A to function type B and back to A gives you the original back. Calling the function after the cast to a different type is what is undefined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.