Search code examples
c++visual-studio-2017googletest

static inline associative collection included in 2 gtest files throws read access violation


I have a very simple class with a static inline member variable that is throwing "read access violation" if it's included in more than 1 test file. The error is thrown in the destructor after all tests pass. It also only occurs in debug builds. I suspect it's trying to delete the member variable more than once.

Note that the example below has no actual tests as the error occurs with and without test functions. As far as I can tell, this happens with any associative collection (std::map, std::set, boost::ptree, std::unordered_map, etc.). It does not happen with literals or sequence containers like std::array, std::vector, etc.

I'm using Visual Studio 2017 - 15.9.33

What can I do to get around this error while keeping the static inline?

Foo.h

#pragma once
#include <map>
class Foo
{
  static inline std::map<int, int> my_map;
}

EmptyOneTest.cpp

#include "gtest/gtest.h"
#include "Foo.h"

TestTwo.cpp

#include "gtest/gtest.h"
#include "Foo.h"

Solution

  • Your analysis about double-calling the destructor is probably right. It does not happen with vectors and arrays because their own destructors are trivial, and it does not happen in release builds because the compiler optimizes out the construction and destruction of an unused object.

    It looks like you've discovered an unpleasant limitation of VS's compiler, and may need to go for a work-around, e.g. Meyer's singleton:

    static inline std::map<int,int>& my_map() {
        static std::map<int,int> res;
        return res;
    }