5

Alright, I think the title is sufficiently descriptive (yet confusing, sorry).

I'm reading this library: Timer1.

In the header file there is a public member pointer to a function as follows:

class TimerOne
{
  public:
  void (*isrCallback)();  // C-style ptr to `void(void)` function
};

There exists an instantiated object of the TimerOne class, called "Timer1".

Timer1 calls the function as follows:

Timer1.isrCallback();

How is this correct? I am familiar with calling functions via function pointers by using the dereference operator.

Ex:

(*myFunc)();

So I would have expected the above call via the object to be something more like:

(*Timer1.isrCallback)();

So, what are the acceptable options for calling functions via function pointers, as both stand-alone function pointers and members of an object?

See also:

  1. [very useful!] Typedef function pointer?
  2. Kind of related, and asked 9 years later by someone else: Correct syntax use function pointers in C

Summary of the answer:

These are all valid and fine ways to call a function pointer:

myFuncPtr();
(*myFuncPtr)();
(**myFuncPtr)();
(***myFuncPtr)();
// etc.
(**********************************f)(); // also valid
1
  • A function pointer, that happens to be a class member, is still a function pointer. Why should the rules be any different? Commented Aug 7, 2015 at 3:16

3 Answers 3

5

Things you can do with a function pointer.

1: The first is calling the function via explicit dereference:

int myfunc(int n)
{
}

int (*myfptr)(int) = myfunc; 

(*myfptr)(nValue); // call function myfunc(nValue) through myfptr.

2: The second way is via implicit dereference:

int myfunc(int n)
{
}

int (*myfptr)(int) = myfunc;

myfptr(nValue); // call function myfunc(nValue) through myfptr.

As you can see, the implicit dereference method looks just like a normal function call -- which is what you’d expect, since function are simply implicitly convertible to function pointers!!

In your code:

void foo()
{
    cout << "hi" << endl;
}

class TimerOne
{
public:

    void(*isrCallback)();
};


int main()
{

    TimerOne Timer1;
    Timer1.isrCallback = &foo;   //Assigning the address
    //Timer1.isrCallback = foo;   //We could use this statement as well, it simply proves function are simply implicitly convertible to function pointers. Just like arrays decay to pointer.
    Timer1.isrCallback();         //Implicit dereference
    (*Timer1.isrCallback)();      //Explicit dereference
        return 0;
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks! Can you add the examples through the object too please, just to make sure I have clarity on where parenthesis go? ex: Timer1.isrCallback(). <--rewrite with the other option.
Since it looks like you may have missed it: your code comments didn't quite make it into the code blocks.
@Nishant, thanks! What would this mean exactly, then? Timer1.*isrCallback();
@GabrielStaples, It dereferences the result of isrCallback, as shown here.
@Nishant, Function names are not pointers to functions the same way array names are not pointers. This is illustrated here. Functions are simply implicitly convertible to function pointers.
|
4

You don't have to dereference a function pointer to call it. According to the standard ([expr.call]/1),

The postfix expression shall have function type or pointer to function type.

So (*myFunc)() is valid, and so is myFunc(). In fact, (**myFunc)() is valid too, and you can dereference as many times as you want (can you figure out why?)

3 Comments

Brian, I just read about you on Quora the other day (quora.com/Brian-Bi-1). I didn't expect an answer from you. OK...can I figure out why? Perhaps because a function itself is a pointer, and you can't dereference a pointer beyond its outermost level?...not sure.
Can I figure out why? Because the compiler was designed that way. It treats a function the same as a pointer to a function which is the same as a pointer to a pointer to a function, apparently. The compiler is programmed to treat functions as addresses in memory. I don't know, what's the answer why? I'd like to hear your answer. I'm sure you can provide more insight.
@GabrielStaples A function is converted to a function pointer whenever it appears in a context where such conversion is required. So if you dereference a function pointer to get a function, you can always dereference it a second time: the * operator requires a pointer, so the function just gets converted back to a function pointer. This can be done as many times as you want.
2

You asked:

Timer1 calls the function as follows:

Timer1.isrCallback();

How is this correct?

The type of Timer1.isrCallback is void (*)(). It is a pointer to a function. That's why you can use that syntax.

It is similar to using:

void foo()
{
}

void test_foo()
{
   void (*fptr)() = foo;
   fptr();
}

You can also use:

void test_foo()
{
   void (*fptr)() = foo;
   (*fptr)();
}

but the first form is equally valid.

Update, in response to comment by OP

Given the posted definition of the class you would use:

(*Timer1.isrCallback)(); 

To use

(Timer1.*isrCallback)(); 

isrCallback has to be defined as a non-member variable of whose type is a pointer to a member variable of TimerOne.

void (TimerOne::*isrCallback)();

Example:

#include <iostream>

class TimerOne
{
  public:
  void foo()
  {
     std::cout << "In TimerOne::foo();\n";
  }
};

int main()
{
   TimerOne Timer1;
   void (TimerOne::*isrCallback)() = &TimerOne::foo;
   (Timer1.*isrCallback)();
}

Output:

In TimerOne::foo();

(Test this code)


If you want to define isrCallbak as a member variable of TimerOne, you'll need to use:

#include <iostream>

class TimerOne
{
  public:
  void (TimerOne::*isrCallback)();
  void foo()
  {
     std::cout << "In TimerOne::foo();\n";
  }
};

int main()
{
   TimerOne Timer1;
   Timer1.isrCallback = &TimerOne::foo;

   // A little complicated syntax.
   (Timer1.*(Timer1.isrCallback))();
}

Output:

In TimerOne::foo();

(Test this code)

1 Comment

For doing it through an object, would the latter form look like this: (*Timer1.isrCallback)(); or this Timer1.*isrCallback();? What's the difference?

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.