Strange debug and release behavior in Gcc5.3.0

Situation

I use GCC 5.3.0 provided by Mingw in window 7, and gtest to implement and run unit tests.

In my project, I have a computer hierarchy that implements the Computer interface, as shown below:

 class Dataset; // Not // Interface Computer class Computer { public: // Destructor virtual to enable vmap virtual ~Computer() noexcept = default; // Pure virtual fonctions virtual bool preCompute(Dataset &datas) const = 0; virtual void compute(Dataset &datas) const = 0; }; 

I provide an abstract implementation of this interface as ChainableComputer , which implements another interface ( Chainable ) and the default implementation is precompute . See below.

 class ChainableComputer : public Computer, public Chainable { public: bool preCompute(Dataset &dataset) const override; }; 

These classes are in a namespace called core , and are packaged in core.dll

In another dll, I have an implementation of ChainableComputer in a different domain namespace.

Some of the implementations are simple, and there is nothing to do in preCompute, so they implement the calculations in the same way:

 class SomeComputerImpl : public ChainableComputer{ /// ... void compute(Dataset &datas) const override final{ auto result = preCompute(datas); if(!result){ throw; } } }; 

This code was distributed, so I decided to reorganize and add the protected method to the computer:

 class Computer { /// ... protected: // Helper function for some implementations of Computer void doPrecomputeOrThrow(Dataset &datas) const{ auto result = preCompute(datas); if(!result){ throw; } } } 

I do not consider this behavior standard for a computer, but it gives me the opportunity to change the implementation of these computers, as shown below:

 class SomeComputerImpl : public ChainableComputer{ /// ... void compute(Dataset &datas) const override final{ doPrecomputeOrThrow(Dataset &datas); } }; 

It compiles and works well in the application and in unit test ... if I compile and run in Release mode.

If I choose Debug, compilation works, the application works, but there are no tests.

I am trying to understand that this can happen, but I cannot understand what might be wrong. I think he has something with the linker, and the fact that the interface, the abstract implementation and the concrete implementation are separated by the DLL, and that we run this material in another executable ...

What have i tried

  • ChainableComputer directly in test => works as expected
  • Play from inline or __attribute__(always_inline) to doPrecomputeOrThrow => no effect
  • Implementation of doPrecomputeOrThrow in the namespace (passing Computer * as an argument), in core.dll => no effect
  • The implementation of doPrecomputeOrThrow in the namespace (passing Computer * as an argument) in domain.dll => works as expected
  • Implementing doPrecomputeOrThrow as a template in the class or in the namespace with Computer as the template parameter (see below) => works as expected
  • Implementing doPrecomputeOrThrow as a template in the class, with Dataset as the template parameter (see below) => no effect

    // Template that works as a member of Computer (static or not), or // in the namespace template void doPrecomputerOrThrows (AComputer * c, Dataset & datas);

    // Template that does not work as a member Computer template void doPrecomputerOrThrows (ADataset & datas);

Question

Is there anyone who has an idea of ​​what is going on?

+5
source share

Source: https://habr.com/ru/post/1260594/


All Articles