Search code examples
c++undefined-behaviorlifetime

Storing address of address of function?


Does this program have undefined behavior?

struct Storage {
    void store(void (*&&fp)())  { fpp = &fp; }
    void call() const           { (*fpp)(); }

    void (**fpp)();
};

void f();

int main() {
    Storage s;
    s.store(&f);    // I think, the temporary variable &F is freed at the ';'
    s.call();
}

Solution

  • Yes, this is UB.

    We can remove all the functions to make it simpler:

    #include <iostream>
    
    struct Storage {
        void store(int* && fp)  { fpp = &fp; }
        void call() const           { std::cout << *fpp; }
    
        int** fpp;
    };
    
    int main() {
        int i = 13;
        Storage s;
        s.store(&i); 
        s.call();
    }
    

    You could go even further to remove double pointer, but this should be clear as well. fpp is a pointer to local variable fp that goes out of scope immediately after constructor ends. Dereferencing that pointer is UB.

    For additional proof, your original code triggers AddressSanitizer errors: https://godbolt.org/z/ba4vEbznb