vendredi 29 juin 2018

Defining a code section within which a different code path is executed

Is it possible to define a section or scope in my code within which a different code path is executed, without using a global or passed-down state variable?

For debugging purposes, I want to be able to surround a section of faulty code with a scope or #define to temporarily switch on pre-defined debugging behavior within this section, e.g. use debug data, a more precise data type, an already validated algorithm, … This needs to work in a multi-threaded application in which multiple threads will likely execute the same shared code concurrently, but only some of them have called this code from within the defined section.

For example, here is some pseudo-code that is not working, but might illustrate what I'd like to do. A static expensive function that is called from several places concurrently:

Result Algorithms::foo()
{
#ifdef DEBUG_SECTION
    return Algorithms::algorithmPrecise(dataPrecise);
#else
    return Algorithms::algorithmOptimized(dataOptimized);
#endif
}

Three classes of which instances need to be updated frequently:

Result A::update()
{
    return Algorithms::foo();
}

Result B::update()
{
    Result result;

#define DEBUG_SECTION
        ...

        result = a.update() + 1337;

        ...
#undef DEBUG_SECTION

    return result;
}

Result C::update()
{
    return a.update();
}

As you can see, class A directly calls foo(), whereas in class B, foo() is called indirectly by calling a.update() and some other stuff. Let us assume B::update() returns a wrong result, so I want to be able to use the debug implementation of foo() only from this location. In C::update(), the optimized version should still be used.

My conceptual idea is to define a DEBUG_SECTION around the faulty code which would use the debug implementation at this location. This, however, does not work in practice, as Algorithms::foo() is compiled once with DEBUG_SECTION not being defined. In my application, Algorithms, A, B, and C are located in separate libraries.

I want that within a section defined in the code, a different code section within shared code is executed. However, outside of this section I still want execution of the original code, which at runtime will happen concurrently, so I cannot simply use a state variable. I could add a debugFlag parameter to each call within the DEBUG_SECTION that is passed down in each recursive call that is then provided to Algorithms::foo(), but this is extremely prone to errors (you must not miss any calls, but the section could be quite huge, spread over different files, …) and quite messy in a larger system. Is there any better way to do this?

I need a solution for C++11 and MSVC.

Aucun commentaire:

Enregistrer un commentaire