2

Is it valid to change a pointer to a function (fun here) from a function which was pointed to and during execution (foo)?

using fun_p = void (*) ();

void foo ();
void boo ();

fun_p fun = &foo;

void foo () {
    std::cout << "foo\n";
    fun = &boo;
}
void boo () {
    std::cout << "boo\n";
}

int main () {
    (*fun) ();
    (*fun) ();
    return 0;
}

The reason why I want to do this is to run either foo() or boo(), starting with foo(). Once condition is met in foo() I want to change it once, and since next iteration (the code would be run in a loop of course), boo() is invoked.

Artur Pyszczuk
  • 1,920
  • 1
  • 16
  • 23
  • 3
    Why wouldn't it be? – bitmask Jan 04 '23 at 07:40
  • 1
    The variable `fun` is like any other variable. You can assign any valid value to it, at any time. – Some programmer dude Jan 04 '23 at 07:40
  • 2
    With that said, from a readability and maintainability perspective this is not very good, IMO. How would a casual reader know which function would be called at a given point in the program? – Some programmer dude Jan 04 '23 at 07:42
  • @Someprogrammerdude Said it pretty well. While yes, it's legal, it's not the most legible way of doing things. One way of doing it, would be to create a separate function which does it for you. `handleFun1CallComplete` or something similar. – SimonC Jan 04 '23 at 07:44
  • What about checking condition in a loop every iteration when you can do it only once? Thats the reason I think about that idea. – Artur Pyszczuk Jan 04 '23 at 07:45
  • @ArturPyszczuk Likely [branch-predicted out](https://stackoverflow.com/a/11227902/430766). And jump indirection is not free. Let alone the fact that inlining will be much harder if not impossible. If possible unroll the first loop iteration. – bitmask Jan 04 '23 at 07:48
  • 3
    Style suggestion: `(*fun)()` => `fun()` – Chris Jan 04 '23 at 07:48
  • @Someprogrammerdude Having a state machine (state machine design pattern) as well does not give a casual reader information which state is currently set, yet this is very common and good design pattern. – Artur Pyszczuk Jan 04 '23 at 07:49
  • That feels like a case of premature optimization. – Some programmer dude Jan 04 '23 at 07:49
  • 1
    With a state-machine you can always say what happens for each specific state. With your function pointer it's not possible to know which function will actually be called, the state is hidden. – Some programmer dude Jan 04 '23 at 07:51
  • 1
    Also note the `&` before `&foo` and `&boo` isn't necessary. You can simply write `fun_p fun = foo;` along with `fun = boo;` – David C. Rankin Jan 04 '23 at 08:42
  • Depending on the context, an alternative could be to let `foo()` return a bool which is true when it is done. Then `foo()` can be called until it returns true after which a second loop is entered which calls `boo()`. This way you will only have to check a condition while `foo()` is running and avoid the issues noted in the comments above. – nielsen Jan 04 '23 at 11:38

1 Answers1

2

Yes: the function pointer isn’t “in use” during the call. Consider that it might be a prvalue and thus not be stored anywhere:

(cond ? &f : &g)();
Davis Herring
  • 36,443
  • 4
  • 48
  • 76