Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer to a procedure

Does it possible to invoke a procedure via pointer? I haven't found anything about it on the internet, but the following experimental code compiles without warnings.

#include <iostream>
#include <ctime>

using namespace std;

void PrintCurrentClock()
{
    cout<<clock()<<endl;
}

void PrintCurrentTimeStamp()
{
    cout<<time(0)<<endl;
}


int main()
{
    void* pF = PrintCurrentClock;

    pF;

    pF = PrintCurrentTimeStamp;

    pF;

    system("Pause");
    return 0;
}

The output is empty, as if the *pF was somewhat "transparent".

like image 910
0x6B6F77616C74 Avatar asked Jul 04 '26 07:07

0x6B6F77616C74


2 Answers

Both C and C++ have function pointers that let you do what you are looking for:

void (*pf)(void);
pf = FunctionWithVeryVeryVeryLongNameThatPrintsTheCurrentClockStateUsingStdCoutOutputStream;
pf();

The void in parentheses is optional.

The reason you did not find anything on the topic is that for historic reasons both functions and procedures in C are called functions (the reason is that there were no void in the original language - procedures returned int by default, and the return value was ignored). C++ inherited this naming convention.

like image 89
Sergey Kalinichenko Avatar answered Jul 05 '26 21:07

Sergey Kalinichenko


What you want are function pointers:

void (*pF)() = PrintCurrentClock;
pF();

(some people argue that writing &PrintCurrentClock is better style)

Notice that, as you can see, function pointers have a quite awkward syntax (especially if you start to have function pointers with "strange" arguments) and can prevent some compiler optimizations to work correctly, so they are usually used only when actually needed (e.g. for callbacks, although in C++ functors are often preferred).


Why does your code compile, although it doesn't work as expected? In

void* pF = PrintCurrentClock;

PrintCurrentClock is a void (*pF)(), which is implicitly converted to void *1; then, writing

pF;

you are evaluating the expression pF and discarding its return value - which is effectively a no-op (exactly as if you wrote 5; or any other expression that does not involve a function call).


  1. Actually, this conversion shouldn't happen automatically, since the C++ standard do not provide an implicit conversion from function pointers to void *. Compiling this with g++ 4.6 correctly produces the errors:

    matteo@teolapmint ~/cpp $ g++ -Wall -Wextra -ansi -pedantic testfuncptr.cpp 
    testfuncptr.cpp: In function ‘int main()’:
    testfuncptr.cpp:19:20: error: invalid conversion from ‘void (*)()’ to ‘void*’ [-fpermissive]
    testfuncptr.cpp:21:15: warning: statement has no effect [-Wunused-value]
    testfuncptr.cpp:23:22: error: invalid conversion from ‘void (*)()’ to ‘void*’ [-fpermissive]
    testfuncptr.cpp:25:23: warning: statement has no effect [-Wunused-value]
    testfuncptr.cpp:27:39: error: ‘system’ was not declared in this scope
    

    which tells you that those conversions are not admitted, that the pF; instructions are no-ops and that you forgot #include <cstdlib> (although system("pause"); is not portable anyway).

like image 32
Matteo Italia Avatar answered Jul 05 '26 21:07

Matteo Italia



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!