3

I was testing for multiples ways of storing and using a function reference for a function named foo.

#include <iostream>

using Function = void (&)(void); // Reference to Function

void foo(void)
{
    std::cout << "Foo called succesfully" << std::endl;
}

Firstly, I tried to store a direct reference to foo inside a static member of a Holder class:

class Holder {
public:
    static const Function class_foo;
};

Function Holder::class_foo = foo;

Secondly, I tried to store a direct reference to foo in a global variable:

Function global_foo1 = foo;

Thirdly, I tried to store a reference to its static reference in the Holder class:

const Function& global_foo2 = Holder::class_foo;

Fourthly, I tried to store a copy of its static reference in the Holder class:

Function global_foo3 = Holder::class_foo;

An access violation exception occurs when trying to execute foo using the 3rd (global_foo2) and 4th (global_foo3) cases.

int main(void)
{
    const Function& local_foo = Holder::class_foo;

    local_foo(); // Executes Properly

    Holder::class_foo(); // Executes Properly

    global_foo1(); // Executes Properly

    global_foo2(); // Throws Exception -> Access Violation when Executing

    global_foo3(); // Throws Exception -> Access Violation when Executing

    return 0;
}

Any idea of what I did wrong? Probably because of my lack of knowledge about compilation steps.

Obs: The full code can be executed by just copying each block of code sequentially. My compiler was Microsoft Visual Studio 15.5.2. Also tried the latest version 15.5.6. Still not working in version 15.9.4. Exception proof is here or here.

Nighteen
  • 731
  • 1
  • 7
  • 16
  • I've never seen anyone use a *reference* to a function before, only a *pointer* to a function instead. Do you have the same problems using a pointer instead of a reference? `using Function = void (*)(void); ... = &foo;` – Remy Lebeau Feb 15 '18 at 22:02
  • 1
    Tell me, does it crash when all the code is in one big file, or only when you compile separately and then link? – StoryTeller - Unslander Monica Feb 15 '18 at 22:03
  • @StoryTeller In both cases the code fail to execute. I ran into this problem when compiling in separate files. But then I condensed the code into one file to ask the question. – Nighteen Feb 15 '18 at 22:05
  • @RemyLebeau I tried to use function references, since it should be safer, after seing this -> https://stackoverflow.com/questions/7142883/chow-to-pass-reference-to-function-into-another-function – Nighteen Feb 15 '18 at 22:06
  • Works with gcc http://coliru.stacked-crooked.com/a/bbbfe1e6d2f7722f – Mihayl Feb 15 '18 at 22:13
  • @A.A Definitely a MSVC bug then... It theoretically should work. I am updating mine right now to see if it still throws those exceptions. Edit: Even on the latest version available it still does not work. – Nighteen Feb 15 '18 at 22:16
  • I too must concur it's a compiler bug. The "reference to a reference" shenanigans look weird, but it's ultimately well defined and collapses to a regular reference. I suspected this to be an instance of the static initialization order fiasco, but if it happens with a single translation unit... – StoryTeller - Unslander Monica Feb 15 '18 at 22:20
  • 1
    Note that there is no actual difference between `Function` and `const Function&`. Adding a cv-qualifier or reference-qualifier to a typedef-name which names an lvalue reference type is ignored: https://timsong-cpp.github.io/cppwp/dcl.ref#6 – aschepler Feb 23 '18 at 04:00

1 Answers1

1

The code compiles and executes properly using GCC. It must either be a MSVC compiler bug or bad compiler configuration.

Nighteen
  • 731
  • 1
  • 7
  • 16
  • For anyone interested, I made a complete bug report with the toolset and the command line in Microsoft's developer community [here](https://developercommunity.visualstudio.com/content/problem/199401/c-compiler-generates-access-violation-code-when-gc.html) – Nighteen Feb 15 '18 at 23:12