0
int* b = new int(40); int c = *(int *)b; 

The above cast is working fine.

But similar casting is not working for function pointers

void abc(int a){ cout<<a<<endl; } std::function<void(int)> callback = *(std::function<void(int)>*)abc; // this cast is not working 

What is wrong in the above piece of code?

4
  • what makes you think that void(*)(int) is a std::function<int>*? Commented Nov 30, 2021 at 9:05
  • 2
    @Raildex it's not unreasonable for someone new to C++, or coming from other languages, to assume that a function is a function is a function. The fact that C++ has 3 (4?) semi-compatible ways to represent a handle to a piece of callable code is basically an accident of history Commented Nov 30, 2021 at 9:14
  • You do not need the cast at all: godbolt.org/z/zes3nW1WK Commented Nov 30, 2021 at 9:15
  • Do you understand the difference between int c = *(int *)b; and int c = (int)*b;? Commented Nov 30, 2021 at 9:20

2 Answers 2

3

You cast b to the same type that it already has. This results in a static cast, which doesn't change the value. The type of b is int* and you cast to int*.

You cast abc to an entirely different type. And since the target type is unrelated, this resulst in a reinterpret cast, and accessing the pointed object through the reinterpreted pointer (which is a problem since it points to a function and not an object at all) results in undefined behaviour. The type of abc is void(int) which is a function type and it implicitly decays to void(*)(int) which is a pointer to function type. You cast it to std::function<void(int)>* which is a pointer to object type, where the object type is of the class type that was instantiated from the class template std::function.

What is wrong in the above piece of code?

  • Using C style cast is wrong. Don't do it.
  • Reinterpret casting pointer to an unrelated type is wrong. std::function<...>* is not a pointer to function. std::function is not a function. It's a class template for a function wrapper.
Sign up to request clarification or add additional context in comments.

3 Comments

nitpick on wording: C style casts are not always wrong (but whenever a c-style cast is right, it can be replaced with a proper cast, hence there is no good reason to use it)
@463035818_is_not_a_number It's wrong to use C style casts even if you use them "right".
ok, agreed. I just thought it is worth pointing out the tiny difference between wrong and wrong ;)
1

std::function<void(int)> is not a function. It is a class with an operator(). It has a constructor that you need to invoke to create an instance of that class. For example like this:

std::function<void(int)> callback = abc; 

On the other hand, here:

int* b = new int(40); int c = *(int *)b; 

new int(40) does create an int object and b is a pointer to that object. The cast (int*)b doesn't do anything, because b is already a int* that you can dereference to assign the value of the int to c.


I tried to keep it simple, for a more accurate explanation of what is actually happening in your code I refer you to this answer: https://stackoverflow.com/a/70166958/4117728.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.