Why both of the next examples are the same?

Ex1 : int*(*foo)() = Function;
Ex2: int*(*foo)() = &Function;


Notice: In the second example i'm using & operator.

That means that c++ takes function name as an address of it and this () dereferencing it just like in arrays?

Recommended Answers

All 12 Replies

Yes, that's precisely correct.

Yes, the use of & is optional in this case. Similarly, when calling the function *foo() and foo() will also be the same.

...c++ takes function name as an address of it...

c++ takes the name of the function (as an expression) to be either a reference to the function or a pointer to the function. eg.

#include <iostream>

void foo( void(*pfn)() ) { std::cout << "pointer\n" ; }
void foo( void(&rfn)() ) { std::cout << "reference\n" ; }
void bar() { std::cout << "bar\n" ; }

int main()
{
  bar() ;  // ok
  (*bar)() ; // ok , bar == &bar,  so  (*bar) == bar
  (**bar)() ; // also ok
  (***bar)() ;  // also ok

  foo(bar) ;  // error - ambiguous is bar a reference or a pointer?
}

Why this is legal?

(****bar)() ;

and here is not?
int x =2;
int *ptr = &x;
cout << (***ptr);

???

You're getting confused between two very distinct topics in C/C++ - Pointers, and function pointers, which are both a rather different kettle of fish.

The reason that function pointers can be handled in such a way as shown in your original post is because of the nature of functions themselves.
in C/C++, you can really only do two things with a function - you may call it, or you may take its address.

Contrast this with a variable, you may also take its address, but you may not call it. In addition to this, unlike functions, you can assign to it, and you can obtain the data it stores.

Since functions and variables are so different, it follows that a pointer-to-function behaves differently to a pointer-to-variable.


Just to put the above into context, when you use the name (identifier) of a function, without the trailing parentheses, the compiler already knows that the function cannot have a value stored, therefore the address of the function is returned instead - the & (address-of) operator is unnecessary.

When you use the name/identifier of a variable, the compiler assumes you wish to obtain its stored value. Hence, if you wish to obtain the address of a variable you must explicitly use the '&' (address-of) operator.


The example you posted using the * (dereference) operator is not legal for the same reasons listed above. this is - a function has no stored data value, so explicitly dereferencing a pointer-to-function does nothing.
On the other hand A variable does store a value, so explicitly de-referencing a pointer-to-variable does have an effect (the effect is to return the variable itself). Ordinary non-pointer variables may not be de-referenced (This would be a nonsensical operation)

commented: Nicely put +7
commented: Good one. +19

Why this is legal?
(****bar)() ;

void bar() { /* ...  */ }

int main()
{
  void (*pfn)() = bar ; // ok, bar is treated as &bar
  void (&rfn)() = *pfn ; // ok, *pfn is a reference to the function
  pfn = rfn ; // ok, equivalent to pfn = &rfn ;
  pfn = *bar ; // ok, equivalent to pfn = &*&bar ;
  pfn = **bar ; // ok, equivalent to pfn = &*&*&bar ;
  pfn = ***bar ; // ok, equivalent to pfn = &*&*&*&bar ;
  (*pfn)() ; // ok, call bar
  (****bar)() ; // ok, equivalent to (*pfn)() ;
}
commented: Nice. +19

So its
(***FuncName)()

Its legal because functions have no values so the dereferencing asterik has no effect on the function name?

the dereference operator (*) on a pointer gives a reference to what is pointed to. the address of operator on a reference gives a pointer to what is being referred to. since a reference to a function can be implicitly treated as a pointer (an implicit address of is assumed),
*f == *(&f) == f

it really has got nothing to do with values or data. a void* points to some data (we do not know what it's type is), but cannot be dereferenced. an int* points to an int, so dereferencing it gives us a reference to an int (int&).

So its
(***FuncName)()

Its legal because functions have no values so the dereferencing asterik has no effect on the function name?

Pretty much, yes.


although it would be noteworthy to say that code like this doesn't pass QA when it comes to readability.

void foo()
{
}

int main()
{
    (****foo)();
}

Make sure that when you use the dereference operator, that it actually enhances the readability/meaning of the code, and doesn't detract from it.

what is wrong here?
void foo()
{
cout << "Foo Called";
}

int main()
{
(****foo)();
return 0;
}What is wrong?

Nothing wrong as far as I can see - as long as you #include <iostream> and have a std namespace declaration.

Did it not compile for you? What compiler are you using?

Ah sorry i thought in your post 10 you wrote that something is wrong here i just miss understood, anyway thanks:)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.