Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between these two expressions

Tags:

c++

#include <bits/stdc++.h>
using namespace std;
void test(){
    int a = 100;
    cout << a << endl;
}
int main()
{
    void(*b)() = test;
    (*b)();         //expression one
    b();            //expression two
    return 0;
}

test is a pointer to function, isn't it? (*b)() is a correct form, because it is equivalent to function prototype. But Why is it correct to delete a symbol *? They all produced the right results.

like image 464
init Avatar asked Nov 15 '21 07:11

init


3 Answers

test is a pointer to function, isn't it?

No, it isn't. test is a function.

b is a pointer to function.

But Why is it correct to delete a symbol *?

Because you can also invoke the function call operator on function pointers, and not just functions.

Furthermore, since a function can implicitly convert to a function pointer, this is also equivalent:

(********b)();

What is the difference between these two expressions

One indirects through function pointer and invokes function call operator - which calls the pointed function.

The other invokes function call operator on a function pointer - which implicitly indirects through the pointer and calls the pointed function.

The former requires 3 more characters to write.

like image 141
eerorika Avatar answered Nov 15 '22 01:11

eerorika


test is the function, b is a pointer to function (which points to test); and pointer to function could be used in function-call expression directly.

A pointer to function can be used as the left-hand operand of the function call operator, this invokes the pointed-to function:

Dereferencing a function pointer yields the lvalue identifying the pointed-to function:

int f();
int (*p)() = f;  // pointer p is pointing to f
int (&r)() = *p; // the lvalue that identifies f is bound to a reference
r();             // function f invoked through lvalue reference
(*p)();          // function f invoked through the function lvalue
p();             // function f invoked directly through the pointer

Dereference on b like *b you'll get the pointed function test. As the effect, (*b)(); and b(); do the same thing, i.e. invoke test.

like image 40
songyuanyao Avatar answered Nov 14 '22 23:11

songyuanyao


test is a pointer to function, isn't it?

test is not a pointer to a function. It is a function.

To make the difference between a function and a function pointer more visible consider the following code snippet.

using Fn = void();
using FnPtr = void ( * )( );

Fn test;
FnPtr test_ptr = test;

void test()
{
    int a = 100;
    std::cout << a << std::endl;
}

In this code snippet there are introduced two aliases. The first alias Fn denotes the function type void(). The second alias FnPtr denotes the pointer type void( * )().

So this record

Fn test;

declares the function test while this record

FnPtr test_ptr = test;

declares the function pointer test_ptr that is initialized by the address of the function test because the function designator test used as an initializer in this declaration is implicitly converted to a pointer to the function test. You could rewrite the declaration also the following way

FnPtr test_ptr = &test;

explicitly applying the address of operator.

These two function call expressions

(*b)();
b(); 

differ only in one aspect.

In the first call there is used a function lvalue. Neither implicit conversion from the lvalue to a function pointer is done.

In the second call there is used a function pointer.

From the C++ 14 Standard (5.2.2 Function call)

  1. ...For a call to a non-member function or to a static member function, the postfix expression shall be either an lvalue that refers to a function (in which case the function-to-pointer standard conversion (4.3) is suppressed on the postfix expression), or it shall have pointer to function type

Pay attention to that you could call the function also the following way

( *test )();

In this case the function designator is implicitly converted to a pointer to the function and then after applying the operator * an lvalue to the function is obtained. S you may even write

( ******test )();

or

( *&*&*&test )();
like image 33
Vlad from Moscow Avatar answered Nov 15 '22 01:11

Vlad from Moscow